From 4a7bb89a6478c770cc8174e13356998132031c9c Mon Sep 17 00:00:00 2001 From: lovasoa Date: Fri, 14 Mar 2025 14:47:29 +0000 Subject: [PATCH 01/21] sqlite 3.49 / emscripten 4 / node 22 the worker scripts are now compatible with nodejs worker threads: https://nodejs.org/api/worker_threads.html the worker tests now use node worker threads instead of a browser removes dependency to puppeteer --- .devcontainer/Dockerfile | 44 +- .devcontainer/devcontainer.json | 12 +- Makefile | 6 +- package-lock.json | 2076 +++++++++++-------------------- package.json | 1 - src/worker.js | 38 +- test/test_worker.js | 123 +- 7 files changed, 828 insertions(+), 1472 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 24204861..e6b168d5 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,13 +1,13 @@ # We build our DevContainer on MS' Typescript-Node Devcontainer -# This gives us lots of standard stuff, and lets us layer a few custom things on top, like the Emscripten compiler, Puppeteer +# This gives us lots of standard stuff, and lets us layer a few custom things on top, like the Emscripten compiler # -------------------------------------------------------------------- # BEGIN Standard MS Devcontainer for Typescript-Node # See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.155.1/containers/typescript-node/.devcontainer/base.Dockerfile # [Choice] Node.js version: 14, 12, 10 -ARG VARIANT="16-buster" -FROM mcr.microsoft.com/vscode/devcontainers/typescript-node:0-${VARIANT} +ARG VARIANT="22-bullseye" +FROM mcr.microsoft.com/vscode/devcontainers/typescript-node:1-${VARIANT} # [Optional] Uncomment if you want to install an additional version of node using nvm # ARG EXTRA_NODE_VERSION=10 @@ -24,7 +24,7 @@ FROM mcr.microsoft.com/vscode/devcontainers/typescript-node:0-${VARIANT} # Install EMSDK to /emsdk just like the EMSDK Dockerfile: https://github.com/emscripten-core/emsdk/blob/master/docker/Dockerfile ENV EMSDK /emsdk # We pin the EMSDK version rather than 'latest' so that everyone is using the same compiler version -ENV EMSCRIPTEN_VERSION 3.1.64 +ENV EMSCRIPTEN_VERSION 4.0.5 RUN git clone https://github.com/emscripten-core/emsdk.git $EMSDK @@ -68,38 +68,4 @@ RUN echo ". /emsdk/emsdk_env.sh" >> /etc/bash.bashrc RUN echo 'export EM_NODE_JS="$EMSDK_NODE"' >> /etc/bash.bashrc # END EMSDK -# -------------------------------------------------------------------- - -# -------------------------------------------------------------------- -# BEGIN PUPPETEER dependencies -# Here we install all of the packages depended upon by Chrome (that Puppeteer will use for headless tests). -# We could also take a page from https://github.com/buildkite/docker-puppeteer/blob/master/Dockerfile instead, -# and install the latest stable version of Chrome to get the right dependencies, but that version changes over time, -# so the stable version of Chrome and the version installed by Puppeteer might diverge over time. -# It also means they end up having Chrome downloaded and installed twice. -# We could install the particular version of Chrome that our version of Puppeteer would use and then tell Puppeteer not to download its own version of Chrome, -# but then we'd have to rebuild our Docker container every time we revved Puppeteer, and that feels fiddly too. -# For all of these reasons, it seems safer to simply install the explicit list packages depended upon by Chrome, assume that's unlikely to change -# and move on. - -# List taken from: -# https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md#chrome-headless-doesnt-launch-on-unix -RUN apt-get update \ - && apt-get install -y wget gnupg \ - && wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \ - && sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' \ - && apt-get update \ - && apt-get install -y google-chrome-stable fonts-freefont-ttf libxss1 libxshmfence1 libglu1 \ - --no-install-recommends \ - # Installs the command "sha3sum", which is used check the download integrity of sqlite source. - && apt-get install -y libdigest-sha3-perl \ - && rm -rf /var/lib/apt/lists/* - -# We set this env variable (RUN_WORKER_TEST_WITHOUT_PUPPETEER_SANDBOX=1) this to tell our sql.js test harness to run Puppeteer without the sandbox. -# Otherwise, when we instantiate Puppeteer, we get this error: -# Puppeteer can't start due to a sandbox error. (Details follow.) -# [0321/173044.694524:FATAL:zygote_host_impl_linux.cc(117)] No usable sandbox! Update your kernel or see https://chromium.googlesource.com/chromium/src/+/master/docs/linux/suid_sandbox_development.md for more information on developing with the SUID sandbox. If you want to live dangerously and need an immediate workaround, you can try using --no-sandbox. -ENV RUN_WORKER_TEST_WITHOUT_PUPPETEER_SANDBOX=1 - -# END PUPPETEER -# -------------------------------------------------------------------- +# -------------------------------------------------------------------- \ No newline at end of file diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index ce6189ce..1a028d52 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -4,17 +4,11 @@ "name": "Node.js & TypeScript", "build": { "dockerfile": "Dockerfile", - // Update 'VARIANT' to pick a Node version: 12, 14, 16 + // Update 'VARIANT' to pick a Node version "args": { - "VARIANT": "16-buster" - }, + "VARIANT": "22-bullseye" + } }, - // Set *default* container specific settings.json values on container create. - "settings": {}, - // Add the IDs of extensions you want installed when the container is created. - "extensions": [ - "dbaeumer.vscode-eslint" - ], // Use 'forwardPorts' to make a list of ports inside the container available locally. // "forwardPorts": [], // Use 'postCreateCommand' to run commands after the container is created. diff --git a/Makefile b/Makefile index dc9e4872..45306539 100644 --- a/Makefile +++ b/Makefile @@ -6,9 +6,9 @@ # I got this handy makefile syntax from : https://github.com/mandel59/sqlite-wasm (MIT License) Credited in LICENSE # To use another version of Sqlite, visit https://www.sqlite.org/download.html and copy the appropriate values here: -SQLITE_AMALGAMATION = sqlite-amalgamation-3450200 -SQLITE_AMALGAMATION_ZIP_URL = https://www.sqlite.org/2024/sqlite-amalgamation-3450200.zip -SQLITE_AMALGAMATION_ZIP_SHA3 = 8d9c553b52c7b1656a97fec7907cb00fd1419ac45104e45c76b7c2b81ffe0a9d +SQLITE_AMALGAMATION = sqlite-amalgamation-3490100 +SQLITE_AMALGAMATION_ZIP_URL = https://sqlite.org/2025/sqlite-amalgamation-3490100.zip +SQLITE_AMALGAMATION_ZIP_SHA3 = e7eb4cfb2d95626e782cfa748f534c74482f2c3c93f13ee828b9187ce05b2da7 # Note that extension-functions.c hasn't been updated since 2010-02-06, so likely doesn't need to be updated EXTENSION_FUNCTIONS = extension-functions.c diff --git a/package-lock.json b/package-lock.json index 60bf735c..1eb42f97 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,25 +14,9 @@ "eslint-config-airbnb-base": "^15.0.0", "eslint-plugin-import": "^2.26.0", "jsdoc": "^4.0.2", - "puppeteer": "^22.14.0", "test": "=0.6.0" } }, - "node_modules/@babel/code-frame": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.0.tgz", - "integrity": "sha512-INCKxTtbXtcNbUZ3YXutwMpEleqttcswhAdee7dhuoVrD2cnuc3PqtERBtxkX5nziX9vnBL8WXmSGwv8CuPV6g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.25.9", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-string-parser": { "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", @@ -54,13 +38,13 @@ } }, "node_modules/@babel/parser": { - "version": "7.26.1", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.1.tgz", - "integrity": "sha512-reoQYNiAJreZNsJzyrDNzFQ+IQ5JFiIzAHJg9bn94S3l+4++J7RsIhNMoB+lgP/9tpmiAQqspv+xfdxTSzREOw==", + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.10.tgz", + "integrity": "sha512-6aQR2zGE/QFi8JpDLjUZEPYOs7+mhKXm86VaKFiLP35JQwQb6bwUE+XbvkH0EptsYhbNBSUGaUBLKqxH1xSgsA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.26.0" + "@babel/types": "^7.26.10" }, "bin": { "parser": "bin/babel-parser.js" @@ -70,9 +54,9 @@ } }, "node_modules/@babel/types": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz", - "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==", + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.10.tgz", + "integrity": "sha512-emqcG3vHrpxUKTrxcblR36dcrcoRDvKmnL/dCL6ZsHaShW80qxCAcNhzQZrpeM765VzEos+xOi4s+r4IXzTwdQ==", "dev": true, "license": "MIT", "dependencies": { @@ -84,9 +68,9 @@ } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", - "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.5.1.tgz", + "integrity": "sha512-soEIOALTfTK6EjmKMMoLugwaP0rzkad90iIWd1hMO9ARkSAyjfMfkRRhLvD5qH7vvM0Cg72pieUfR6yh6XxC4w==", "dev": true, "license": "MIT", "dependencies": { @@ -185,9 +169,9 @@ "license": "BSD-3-Clause" }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", "dev": true, "license": "MIT", "dependencies": { @@ -249,9 +233,9 @@ } }, "node_modules/@jsdoc/salty": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/@jsdoc/salty/-/salty-0.2.8.tgz", - "integrity": "sha512-5e+SFVavj1ORKlKaKr2BmTOekmXbelU7dC0cDkQLqag7xfuTPuGMUFx7KWJuv4bYZrTsoL2Z18VVCOKYxzoHcg==", + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/@jsdoc/salty/-/salty-0.2.9.tgz", + "integrity": "sha512-yYxMVH7Dqw6nO0d5NIV8OQWnitU8k6vXH8NtgqAfIa/IUqRMxRv/NUJJ08VEKbAakwxlgBl5PJdrU0dMPStsnw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -299,42 +283,6 @@ "node": ">= 8" } }, - "node_modules/@puppeteer/browsers": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.3.0.tgz", - "integrity": "sha512-ioXoq9gPxkss4MYhD+SFaU9p1IHFUX0ILAWFPyjGaBdjLsYAlZw6j1iLA0N/m12uVHLFDfSYNF7EQccjinIMDA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "debug": "^4.3.5", - "extract-zip": "^2.0.1", - "progress": "^2.0.3", - "proxy-agent": "^6.4.0", - "semver": "^7.6.3", - "tar-fs": "^3.0.6", - "unbzip2-stream": "^1.4.3", - "yargs": "^17.7.2" - }, - "bin": { - "browsers": "lib/cjs/main-cli.js" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@puppeteer/browsers/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@rtsao/scc": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", @@ -342,13 +290,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@tootallnate/quickjs-emscripten": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", - "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -381,39 +322,17 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/node": { - "version": "22.8.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.8.4.tgz", - "integrity": "sha512-SpNNxkftTJOPk0oN+y2bIqurEXHTA2AOZ3EJDDKeJ5VzkvvORSvmQXGQarcOzWV1ac7DCaPBEdMDxBsM+d8jWw==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "undici-types": "~6.19.8" - } - }, - "node_modules/@types/yauzl": { - "version": "2.10.3", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", - "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", "dev": true, "license": "ISC" }, "node_modules/acorn": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", - "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "version": "8.14.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", + "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", "dev": true, "license": "MIT", "bin": { @@ -433,19 +352,6 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/agent-base": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", - "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -506,14 +412,14 @@ "license": "Python-2.0" }, "node_modules/array-buffer-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", - "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.5", - "is-array-buffer": "^3.0.4" + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" }, "engines": { "node": ">= 0.4" @@ -565,16 +471,16 @@ } }, "node_modules/array.prototype.flat": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", - "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -584,16 +490,16 @@ } }, "node_modules/array.prototype.flatmap": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", - "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -603,20 +509,19 @@ } }, "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", - "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", "dev": true, "license": "MIT", "dependencies": { "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.5", + "call-bind": "^1.0.8", "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.2.1", - "get-intrinsic": "^1.2.3", - "is-array-buffer": "^3.0.4", - "is-shared-array-buffer": "^1.0.2" + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" }, "engines": { "node": ">= 0.4" @@ -625,17 +530,14 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ast-types": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", - "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", "dev": true, "license": "MIT", - "dependencies": { - "tslib": "^2.0.1" - }, "engines": { - "node": ">=4" + "node": ">= 0.4" } }, "node_modules/available-typed-arrays": { @@ -654,13 +556,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/b4a": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.7.tgz", - "integrity": "sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==", - "dev": true, - "license": "Apache-2.0" - }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -668,88 +563,6 @@ "dev": true, "license": "MIT" }, - "node_modules/bare-events": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.5.0.tgz", - "integrity": "sha512-/E8dDe9dsbLyh2qrZ64PEPadOQ0F4gbl1sUJOrmph7xOiIxfY8vwab/4bFLh4Y88/Hk/ujKcrQKc+ps0mv873A==", - "dev": true, - "license": "Apache-2.0", - "optional": true - }, - "node_modules/bare-fs": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.3.5.tgz", - "integrity": "sha512-SlE9eTxifPDJrT6YgemQ1WGFleevzwY+XAP1Xqgl56HtcrisC2CHCZ2tq6dBpcH2TnNxwUEUGhweo+lrQtYuiw==", - "dev": true, - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "bare-events": "^2.0.0", - "bare-path": "^2.0.0", - "bare-stream": "^2.0.0" - } - }, - "node_modules/bare-os": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.4.4.tgz", - "integrity": "sha512-z3UiI2yi1mK0sXeRdc4O1Kk8aOa/e+FNWZcTiPB/dfTWyLypuE99LibgRaQki914Jq//yAWylcAt+mknKdixRQ==", - "dev": true, - "license": "Apache-2.0", - "optional": true - }, - "node_modules/bare-path": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-2.1.3.tgz", - "integrity": "sha512-lh/eITfU8hrj9Ru5quUp0Io1kJWIk1bTjzo7JH1P5dWmQ2EL4hFUlfI8FonAhSlgIfhn63p84CDY/x+PisgcXA==", - "dev": true, - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "bare-os": "^2.1.0" - } - }, - "node_modules/bare-stream": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.3.2.tgz", - "integrity": "sha512-EFZHSIBkDgSHIwj2l2QZfP4U5OcD4xFAOwhSb/vlr9PIqyGJGvB/nfClJbcnh3EY4jtPE4zsb5ztae96bVF79A==", - "dev": true, - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "streamx": "^2.20.0" - } - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/basic-ftp": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", - "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.0.0" - } - }, "node_modules/bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", @@ -768,41 +581,6 @@ "concat-map": "0.0.1" } }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -811,17 +589,47 @@ "license": "MIT" }, "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", "dev": true, "license": "MIT", "dependencies": { + "call-bind-apply-helpers": "^1.0.0", "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" }, "engines": { "node": ">= 0.4" @@ -881,21 +689,6 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/chromium-bidi": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.6.3.tgz", - "integrity": "sha512-qXlsCmpCZJAnoTYI83Iu6EdYQpMYdVkCfq08KDh2pmlVqK5t5IA9mGs4/LwCwp4fqisSOMXZxP3HIh8w8aRn0A==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "mitt": "3.0.1", - "urlpattern-polyfill": "10.0.0", - "zod": "3.23.8" - }, - "peerDependencies": { - "devtools-protocol": "*" - } - }, "node_modules/clean-css": { "version": "5.3.3", "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz", @@ -927,21 +720,6 @@ "jsdoc": ">=3.x <=4.x" } }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -986,37 +764,10 @@ "dev": true, "license": "MIT" }, - "node_modules/cosmiconfig": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", - "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", - "dev": true, - "license": "MIT", - "dependencies": { - "env-paths": "^2.2.1", - "import-fresh": "^3.3.0", - "js-yaml": "^4.1.0", - "parse-json": "^5.2.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/d-fischer" - }, - "peerDependencies": { - "typescript": ">=4.9.5" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "license": "MIT", "dependencies": { @@ -1028,26 +779,16 @@ "node": ">= 8" } }, - "node_modules/data-uri-to-buffer": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", - "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 14" - } - }, "node_modules/data-view-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", - "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.6", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" + "is-data-view": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -1057,31 +798,31 @@ } }, "node_modules/data-view-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", - "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" + "is-data-view": "^1.0.2" }, "engines": { "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/inspect-js" } }, "node_modules/data-view-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", - "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.6", + "call-bound": "^1.0.2", "es-errors": "^1.3.0", "is-data-view": "^1.0.1" }, @@ -1093,9 +834,9 @@ } }, "node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "dev": true, "license": "MIT", "dependencies": { @@ -1153,28 +894,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/degenerator": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", - "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ast-types": "^0.13.4", - "escodegen": "^2.1.0", - "esprima": "^4.0.1" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/devtools-protocol": { - "version": "0.0.1312386", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1312386.tgz", - "integrity": "sha512-DPnhUXvmvKT2dFA/j7B+riVLUt9Q6RKJlcppojL5CoRywJJKLDYnRlw0gTFKfgDPHP5E04UoB71SxoJlVZy8FA==", - "dev": true, - "license": "BSD-3-Clause" - }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -1199,21 +918,19 @@ "tslib": "^2.0.3" } }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", "dev": true, "license": "MIT", "dependencies": { - "once": "^1.4.0" + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" } }, "node_modules/entities": { @@ -1229,79 +946,64 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, "node_modules/es-abstract": { - "version": "1.23.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", - "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "version": "1.23.9", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.9.tgz", + "integrity": "sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==", "dev": true, "license": "MIT", "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "arraybuffer.prototype.slice": "^1.0.3", + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "data-view-buffer": "^1.0.1", - "data-view-byte-length": "^1.0.1", - "data-view-byte-offset": "^1.0.0", - "es-define-property": "^1.0.0", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", - "es-set-tostringtag": "^2.0.3", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.4", - "get-symbol-description": "^1.0.2", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.0", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", "hasown": "^2.0.2", - "internal-slot": "^1.0.7", - "is-array-buffer": "^3.0.4", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", "is-callable": "^1.2.7", - "is-data-view": "^1.0.1", - "is-negative-zero": "^2.0.3", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.3", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.13", - "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", + "is-data-view": "^1.0.2", + "is-regex": "^1.2.1", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.0", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.3", "object-keys": "^1.1.1", - "object.assign": "^4.1.5", - "regexp.prototype.flags": "^1.5.2", - "safe-array-concat": "^1.1.2", - "safe-regex-test": "^1.0.3", - "string.prototype.trim": "^1.2.9", - "string.prototype.trimend": "^1.0.8", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.3", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.2", - "typed-array-byte-length": "^1.0.1", - "typed-array-byte-offset": "^1.0.2", - "typed-array-length": "^1.0.6", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.15" + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.18" }, "engines": { "node": ">= 0.4" @@ -1311,14 +1013,11 @@ } }, "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "dev": true, "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, "engines": { "node": ">= 0.4" } @@ -1334,9 +1033,9 @@ } }, "node_modules/es-object-atoms": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", - "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", "dev": true, "license": "MIT", "dependencies": { @@ -1347,40 +1046,44 @@ } }, "node_modules/es-set-tostringtag": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", - "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", "dev": true, "license": "MIT", "dependencies": { - "get-intrinsic": "^1.2.4", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", - "hasown": "^2.0.1" + "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" } }, "node_modules/es-shim-unscopables": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", - "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", + "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", "dev": true, "license": "MIT", "dependencies": { - "hasown": "^2.0.0" + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" } }, "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", "dev": true, "license": "MIT", "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" }, "engines": { "node": ">= 0.4" @@ -1389,16 +1092,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -1412,28 +1105,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/escodegen": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", - "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=6.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" - } - }, "node_modules/eslint": { "version": "8.57.1", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", @@ -1666,20 +1337,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "license": "BSD-2-Clause", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/esquery": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", @@ -1726,27 +1383,6 @@ "node": ">=0.10.0" } }, - "node_modules/extract-zip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" - }, - "bin": { - "extract-zip": "cli.js" - }, - "engines": { - "node": ">= 10.17.0" - }, - "optionalDependencies": { - "@types/yauzl": "^2.9.1" - } - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -1754,13 +1390,6 @@ "dev": true, "license": "MIT" }, - "node_modules/fast-fifo": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", - "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", - "dev": true, - "license": "MIT" - }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -1776,25 +1405,15 @@ "license": "MIT" }, "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", "dev": true, "license": "ISC", "dependencies": { "reusify": "^1.0.4" } }, - "node_modules/fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "pend": "~1.2.0" - } - }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -1841,20 +1460,26 @@ } }, "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", "dev": true, "license": "ISC" }, "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", "dev": true, "license": "MIT", "dependencies": { - "is-callable": "^1.1.3" + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/fs-extra": { @@ -1890,16 +1515,18 @@ } }, "node_modules/function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" }, "engines": { "node": ">= 0.4" @@ -1918,28 +1545,23 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "license": "ISC", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "dev": true, "license": "MIT", "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -1948,32 +1570,30 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", "dev": true, "license": "MIT", "dependencies": { - "pump": "^3.0.0" + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 0.4" } }, "node_modules/get-symbol-description": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", - "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.5", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4" + "get-intrinsic": "^1.2.6" }, "engines": { "node": ">= 0.4" @@ -1982,37 +1602,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-uri": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.3.tgz", - "integrity": "sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==", - "dev": true, - "license": "MIT", - "dependencies": { - "basic-ftp": "^5.0.2", - "data-uri-to-buffer": "^6.0.2", - "debug": "^4.3.4", - "fs-extra": "^11.2.0" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/get-uri/node_modules/fs-extra": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", - "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=14.14" - } - }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -2082,13 +1671,13 @@ } }, "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "dev": true, "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.1.3" + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -2109,11 +1698,14 @@ "license": "MIT" }, "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", "dev": true, "license": "MIT", + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -2142,11 +1734,14 @@ } }, "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", "dev": true, "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, "engines": { "node": ">= 0.4" }, @@ -2155,9 +1750,9 @@ } }, "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "dev": true, "license": "MIT", "engines": { @@ -2218,55 +1813,6 @@ "node": "^14.13.1 || >=16.0.0" } }, - "node_modules/http-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/https-proxy-agent": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", - "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.0.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "BSD-3-Clause" - }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -2278,9 +1824,9 @@ } }, "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2324,43 +1870,50 @@ "license": "ISC" }, "node_modules/internal-slot": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", - "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", - "hasown": "^2.0.0", - "side-channel": "^1.0.4" + "hasown": "^2.0.2", + "side-channel": "^1.1.0" }, "engines": { "node": ">= 0.4" } }, - "node_modules/ip-address": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", - "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", "dev": true, "license": "MIT", "dependencies": { - "jsbn": "1.1.0", - "sprintf-js": "^1.1.3" + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" }, "engines": { - "node": ">= 12" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-array-buffer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", - "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1" + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -2369,35 +1922,31 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true, - "license": "MIT" - }, "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", "dev": true, "license": "MIT", "dependencies": { - "has-bigints": "^1.0.1" + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -2420,9 +1969,9 @@ } }, "node_modules/is-core-module": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", - "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", "dev": true, "license": "MIT", "dependencies": { @@ -2436,12 +1985,14 @@ } }, "node_modules/is-data-view": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", - "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", "dev": true, "license": "MIT", "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", "is-typed-array": "^1.1.13" }, "engines": { @@ -2452,13 +2003,14 @@ } }, "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", "dev": true, "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -2477,14 +2029,39 @@ "node": ">=0.10.0" } }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", "dev": true, "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, "engines": { - "node": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", + "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-proto": "^1.0.0", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-glob": { @@ -2500,10 +2077,10 @@ "node": ">=0.10.0" } }, - "node_modules/is-negative-zero": { + "node_modules/is-map": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", "dev": true, "license": "MIT", "engines": { @@ -2514,13 +2091,14 @@ } }, "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", "dev": true, "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -2540,15 +2118,30 @@ } }, "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -2557,13 +2150,13 @@ } }, "node_modules/is-shared-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", - "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7" + "call-bound": "^1.0.3" }, "engines": { "node": ">= 0.4" @@ -2573,13 +2166,14 @@ } }, "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", "dev": true, "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -2589,13 +2183,15 @@ } }, "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", "dev": true, "license": "MIT", "dependencies": { - "has-symbols": "^1.0.2" + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -2605,14 +2201,27 @@ } }, "node_modules/is-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", - "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", "dev": true, "license": "MIT", "dependencies": { - "which-typed-array": "^1.1.14" + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -2621,22 +2230,42 @@ } }, "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2" + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", "dev": true, "license": "MIT" }, @@ -2647,13 +2276,6 @@ "dev": true, "license": "ISC" }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true, - "license": "MIT" - }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -2677,13 +2299,6 @@ "xmlcreate": "^2.0.4" } }, - "node_modules/jsbn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", - "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", - "dev": true, - "license": "MIT" - }, "node_modules/jsdoc": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-4.0.4.tgz", @@ -2731,13 +2346,6 @@ "dev": true, "license": "MIT" }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true, - "license": "MIT" - }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -2822,13 +2430,6 @@ "node": ">= 0.8.0" } }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true, - "license": "MIT" - }, "node_modules/linkify-it": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", @@ -2879,16 +2480,6 @@ "tslib": "^2.0.3" } }, - "node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=12" - } - }, "node_modules/markdown-it": { "version": "14.1.0", "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", @@ -2931,6 +2522,16 @@ "node": ">= 12" } }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/mdurl": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", @@ -2961,13 +2562,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/mitt": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", - "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", - "dev": true, - "license": "MIT" - }, "node_modules/mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", @@ -2995,16 +2589,6 @@ "dev": true, "license": "MIT" }, - "node_modules/netmask": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", - "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4.0" - } - }, "node_modules/no-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", @@ -3017,9 +2601,9 @@ } }, "node_modules/object-inspect": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", "dev": true, "license": "MIT", "engines": { @@ -3040,15 +2624,17 @@ } }, "node_modules/object.assign": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.5", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", "object-keys": "^1.1.1" }, "engines": { @@ -3108,13 +2694,14 @@ } }, "node_modules/object.values": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", - "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" }, @@ -3153,6 +2740,24 @@ "node": ">= 0.8.0" } }, + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -3185,40 +2790,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/pac-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.2.tgz", - "integrity": "sha512-BFi3vZnO9X5Qt6NRz7ZOaPja3ic0PhlsmCRYLOpN11+mWBCR6XJDqW5RF3j8jm4WGGQZtBA+bTfxYzeKW73eHg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@tootallnate/quickjs-emscripten": "^0.23.0", - "agent-base": "^7.0.2", - "debug": "^4.3.4", - "get-uri": "^6.0.1", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.5", - "pac-resolver": "^7.0.1", - "socks-proxy-agent": "^8.0.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/pac-resolver": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", - "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", - "dev": true, - "license": "MIT", - "dependencies": { - "degenerator": "^5.0.0", - "netmask": "^2.0.2" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/param-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", @@ -3243,25 +2814,6 @@ "node": ">=6" } }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/pascal-case": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", @@ -3310,24 +2862,10 @@ "dev": true, "license": "MIT" }, - "node_modules/pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "dev": true, - "license": "MIT" - }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true, - "license": "ISC" - }, "node_modules/possible-typed-array-names": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", - "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", "dev": true, "license": "MIT", "engines": { @@ -3344,54 +2882,6 @@ "node": ">= 0.8.0" } }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/proxy-agent": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.4.0.tgz", - "integrity": "sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.0.2", - "debug": "^4.3.4", - "http-proxy-agent": "^7.0.1", - "https-proxy-agent": "^7.0.3", - "lru-cache": "^7.14.1", - "pac-proxy-agent": "^7.0.1", - "proxy-from-env": "^1.1.0", - "socks-proxy-agent": "^8.0.2" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "dev": true, - "license": "MIT" - }, - "node_modules/pump": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", - "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", - "dev": true, - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -3412,43 +2902,6 @@ "node": ">=6" } }, - "node_modules/puppeteer": { - "version": "22.15.0", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-22.15.0.tgz", - "integrity": "sha512-XjCY1SiSEi1T7iSYuxS82ft85kwDJUS7wj1Z0eGVXKdtr5g4xnVcbjwxhq5xBnpK/E7x1VZZoJDxpjAOasHT4Q==", - "dev": true, - "hasInstallScript": true, - "license": "Apache-2.0", - "dependencies": { - "@puppeteer/browsers": "2.3.0", - "cosmiconfig": "^9.0.0", - "devtools-protocol": "0.0.1312386", - "puppeteer-core": "22.15.0" - }, - "bin": { - "puppeteer": "lib/esm/puppeteer/node/cli.js" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/puppeteer-core": { - "version": "22.15.0", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-22.15.0.tgz", - "integrity": "sha512-cHArnywCiAAVXa3t4GGL2vttNxh7GqXtIYGym99egkNJ3oG//wL9LkvO4WE8W1TJe95t1F1ocu9X4xWaGsOKOA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@puppeteer/browsers": "2.3.0", - "chromium-bidi": "0.6.3", - "debug": "^4.3.6", - "devtools-protocol": "0.0.1312386", - "ws": "^8.18.0" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -3470,23 +2923,41 @@ ], "license": "MIT" }, - "node_modules/queue-tick": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", - "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/regexp.prototype.flags": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz", - "integrity": "sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", "set-function-name": "^2.0.2" }, "engines": { @@ -3506,16 +2977,6 @@ "node": ">= 0.10" } }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/requizzle": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.4.tgz", @@ -3527,19 +2988,22 @@ } }, "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", "dev": true, "license": "MIT", "dependencies": { - "is-core-module": "^2.13.0", + "is-core-module": "^2.16.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -3555,9 +3019,9 @@ } }, "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", "dev": true, "license": "MIT", "engines": { @@ -3607,15 +3071,16 @@ } }, "node_modules/safe-array-concat": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", - "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4", - "has-symbols": "^1.0.3", + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", "isarray": "^2.0.5" }, "engines": { @@ -3625,16 +3090,33 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/safe-regex-test": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", - "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.6", + "call-bound": "^1.0.2", "es-errors": "^1.3.0", - "is-regex": "^1.1.4" + "is-regex": "^1.2.1" }, "engines": { "node": ">= 0.4" @@ -3687,6 +3169,21 @@ "node": ">= 0.4" } }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -3738,16 +3235,17 @@ } }, "node_modules/side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -3756,45 +3254,60 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/smart-buffer": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", - "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", "dev": true, "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, "engines": { - "node": ">= 6.0.0", - "npm": ">= 3.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/socks": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", - "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", "dev": true, "license": "MIT", "dependencies": { - "ip-address": "^9.0.5", - "smart-buffer": "^4.2.0" + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" }, "engines": { - "node": ">= 10.0.0", - "npm": ">= 3.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/socks-proxy-agent": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.4.tgz", - "integrity": "sha512-GNAq/eg8Udq2x0eNiFkr9gRg5bA7PXEWagQdeRX4cPSG+X/8V38v637gim9bjFptMk1QWsCTr0ttrJEiXbNnRw==", + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", "dev": true, "license": "MIT", "dependencies": { - "agent-base": "^7.1.1", - "debug": "^4.3.4", - "socks": "^2.8.3" + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" }, "engines": { - "node": ">= 14" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/source-map": { @@ -3818,54 +3331,20 @@ "source-map": "^0.6.0" } }, - "node_modules/sprintf-js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", - "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/streamx": { - "version": "2.20.1", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.20.1.tgz", - "integrity": "sha512-uTa0mU6WUC65iUvzKH4X9hEdvSW7rbPxPtwfWiLMSj3qTdQbAiUboZTxauKfpFuGIGa1C2BYijZ7wgdUXICJhA==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-fifo": "^1.3.2", - "queue-tick": "^1.0.1", - "text-decoder": "^1.1.0" - }, - "optionalDependencies": { - "bare-events": "^2.2.0" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/string.prototype.trim": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", - "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", - "es-object-atoms": "^1.0.0" + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -3875,16 +3354,20 @@ } }, "node_modules/string.prototype.trimend": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", - "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -3969,37 +3452,10 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/tar-fs": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.6.tgz", - "integrity": "sha512-iokBDQQkUyeXhgPYaZxmczGPhnhXZ0CmrqI+MOb/WFGS9DW5wnfrLgtjUJBvz50vQ3qfRwJ62QVoCFu8mPVu5w==", - "dev": true, - "license": "MIT", - "dependencies": { - "pump": "^3.0.0", - "tar-stream": "^3.1.5" - }, - "optionalDependencies": { - "bare-fs": "^2.1.1", - "bare-path": "^2.1.0" - } - }, - "node_modules/tar-stream": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", - "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "b4a": "^1.6.4", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" - } - }, "node_modules/terser": { - "version": "5.36.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.36.0.tgz", - "integrity": "sha512-IYV9eNMuFAV4THUspIRXkLakHnV6XO7FEdtKjf/mDyrnqUg9LnlOn6/RwRvM9SZjR4GUq8Nk8zj67FzVARr74w==", + "version": "5.39.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.39.0.tgz", + "integrity": "sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -4031,13 +3487,6 @@ "ansi-font": "0.0.2" } }, - "node_modules/text-decoder": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.1.tgz", - "integrity": "sha512-x9v3H/lTKIJKQQe7RPQkLfKAnc9lUTkWDypIQgTzPJAq+5/GCDHonmshfvlsNSj58yyshbIJJDLmU15qNERrXQ==", - "dev": true, - "license": "Apache-2.0" - }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -4045,13 +3494,6 @@ "dev": true, "license": "MIT" }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true, - "license": "MIT" - }, "node_modules/tsconfig-paths": { "version": "3.15.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", @@ -4066,9 +3508,9 @@ } }, "node_modules/tslib": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.0.tgz", - "integrity": "sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "dev": true, "license": "0BSD" }, @@ -4099,32 +3541,32 @@ } }, "node_modules/typed-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", - "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "is-typed-array": "^1.1.13" + "is-typed-array": "^1.1.14" }, "engines": { "node": ">= 0.4" } }, "node_modules/typed-array-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", - "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" }, "engines": { "node": ">= 0.4" @@ -4134,18 +3576,19 @@ } }, "node_modules/typed-array-byte-offset": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", - "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", "dev": true, "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" }, "engines": { "node": ">= 0.4" @@ -4155,18 +3598,18 @@ } }, "node_modules/typed-array-length": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", - "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", "dev": true, "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", - "has-proto": "^1.0.3", "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0" + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" }, "engines": { "node": ">= 0.4" @@ -4183,32 +3626,24 @@ "license": "MIT" }, "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", + "call-bound": "^1.0.3", "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/unbzip2-stream": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", - "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer": "^5.2.1", - "through": "^2.3.8" - } - }, "node_modules/underscore": { "version": "1.13.7", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.7.tgz", @@ -4216,14 +3651,6 @@ "dev": true, "license": "MIT" }, - "node_modules/undici-types": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", - "dev": true, - "license": "MIT", - "optional": true - }, "node_modules/universalify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", @@ -4244,13 +3671,6 @@ "punycode": "^2.1.0" } }, - "node_modules/urlpattern-polyfill": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz", - "integrity": "sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==", - "dev": true, - "license": "MIT" - }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -4268,34 +3688,45 @@ } }, "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", "dev": true, "license": "MIT", "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/which-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", - "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", "dev": true, "license": "MIT", "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.2" + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" }, "engines": { "node": ">= 0.4" @@ -4304,32 +3735,55 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", "dev": true, "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "node_modules/which-typed-array": { + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", "dev": true, "license": "MIT", "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" }, "engines": { - "node": ">=10" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" } }, "node_modules/wrappy": { @@ -4339,28 +3793,6 @@ "dev": true, "license": "ISC" }, - "node_modules/ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", - "dev": true, - "license": "MIT", - "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 - } - } - }, "node_modules/xmlcreate": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz", @@ -4368,56 +3800,6 @@ "dev": true, "license": "Apache-2.0" }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", @@ -4430,16 +3812,6 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } - }, - "node_modules/zod": { - "version": "3.23.8", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", - "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } } } } diff --git a/package.json b/package.json index 480a55ee..e539e772 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,6 @@ "eslint-config-airbnb-base": "^15.0.0", "eslint-plugin-import": "^2.26.0", "jsdoc": "^4.0.2", - "puppeteer": "^22.14.0", "test": "=0.6.0" } } diff --git a/src/worker.js b/src/worker.js index 9aa544f8..10c6f3c1 100644 --- a/src/worker.js +++ b/src/worker.js @@ -88,12 +88,36 @@ function onError(err) { }); } +db = null; +var sqlModuleReady = initSqlJs(); + +function global_sqljs_message_handler(event) { + return sqlModuleReady + .then(onModuleReady.bind(event)) + .catch(onError.bind(event)); +} + if (typeof importScripts === "function") { - db = null; - var sqlModuleReady = initSqlJs(); - self.onmessage = function onmessage(event) { - return sqlModuleReady - .then(onModuleReady.bind(event)) - .catch(onError.bind(event)); - }; + self.onmessage = global_sqljs_message_handler; +} + +if (typeof require === "function") { + // eslint-disable-next-line global-require + var worker_threads = require("worker_threads"); + var parentPort = worker_threads.parentPort; + // eslint-disable-next-line no-undef + globalThis.postMessage = parentPort.postMessage.bind(parentPort); + parentPort.on("message", function onmessage(data) { + var event = { data: data }; + global_sqljs_message_handler(event); + }); + + if (typeof process !== "undefined") { + process.on("uncaughtException", function uncaughtException(err) { + postMessage({ error: err.message }); + }); + process.on("unhandledRejection", function unhandledRejection(err) { + postMessage({ error: err.message }); + }); + } } diff --git a/test/test_worker.js b/test/test_worker.js index 64128401..42d11db4 100644 --- a/test/test_worker.js +++ b/test/test_worker.js @@ -1,80 +1,82 @@ -// TODO: Instead of using puppeteer, we could use the new Node 11 workers via -// node --experimental-worker test/all.js -// Then we could do this: -//const { Worker } = require('worker_threads'); -// But it turns out that the worker_threads interface is just different enough not to work. -var puppeteer = require("puppeteer"); -var path = require("path"); -var fs = require("fs"); -const { env } = require("process"); +const { Worker } = require("worker_threads"); +const path = require("path"); -class Worker { - constructor(handle) { - this.handle = handle; - } - static async fromFile(file) { - const browser = await Worker.launchBrowser(); - const page = await browser.newPage(); - const source = fs.readFileSync(file, 'utf8'); - const worker = await page.evaluateHandle(x => { - const url = URL.createObjectURL(new Blob([x]), { type: 'application/javascript; charset=utf-8' }); - return new Worker(url); - }, source); - return new Worker(worker); - } +class SQLWorker { + constructor(worker) { + this.worker = worker; + this.callbacks = new Map(); + this.nextId = 1; - static async launchBrowser(){ - try{ - return await puppeteer.launch({ headless: "new" }); - } - catch(e){ - if (e.stack.includes('No usable sandbox!')){ - // It's possible that this exception is n expected error related to not having the ability to create a sandboxed user for Puppeteer in Docker. - // One way around this is to set up the Dockerfile to have a sandboxed user. - // Details on getting Puppeteer running sandboxed while in Docker are here: - // https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md#running-puppeteer-in-docker - // That seemed kinda complicated, so I'm working around it more quickly/straightforwardly by looking for an env variable we set in the Docker fil `RUN_WORKER_TEST_WITHOUT_PUPPETEER_SANDBOX`. - // -- Taytay - if (env['RUN_WORKER_TEST_WITHOUT_PUPPETEER_SANDBOX']=="1"){ - // This tells puppeteer to launch without worrying about the sandbox. - // That's not "safe" if you don't trust the code you're loading in the browser, - // but we're in a container and we know what we're testing. - return await puppeteer.launch({ - args: ['--no-sandbox', '--disable-setuid-sandbox'], - headless: 'new' - }); - } - else { - console.warn("Puppeteer can't start due to a sandbox error. (Details follow.)\nFor a quick, but potentially dangerous workaround, you can set the environment variable 'RUN_WORKER_TEST_WITHOUT_PUPETEER_SANDBOX=1'.\nYou can also simply run this test in the Docker container defined in .devcontainer/Dockerfile."); + this.worker.stderr.on('data', (data) => { + console.log(data); + }); + + this.worker.stdout.on('data', (data) => { + console.log(data); + }); + + this.worker.on('message', (data) => { + if (data.error) { + console.log("Worker error: ", data.error); + for (const callback of this.callbacks.values()) { + callback.reject(data.error); } + return; } - // If we're here, we couldn't get out of this cleanly. Re-throw - throw e; - } + const callback = this.callbacks.get(data.id); + if (callback) { + this.callbacks.delete(data.id); + callback.resolve(data); + } else { + console.log("Received message from worker but no callback found for id", data); + } + }); + + this.worker.on('error', (err) => { + console.log("Worker error", err); + for (const callback of this.callbacks.values()) { + callback.reject(err); + } + this.callbacks.clear(); + }); + } + + static async fromFile(file) { + // Create a worker directly from the file + const worker = new Worker(file); + return new SQLWorker(worker); } async postMessage(msg) { - return await this.handle.evaluate((worker, msg) => { - return new Promise((accept, reject) => { - setTimeout(reject, 20000, new Error("time out")); - worker.onmessage = evt => accept(evt.data); - worker.onerror = reject; - worker.postMessage(msg); - }) - }, msg); + return new Promise((resolve, reject) => { + const id = msg.id || this.nextId++; + const messageWithId = { ...msg, id }; + + this.callbacks.set(id, { resolve, reject }); + + // Set a timeout to reject the promise if no response is received + setTimeout(() => { + if (this.callbacks.has(id)) { + this.callbacks.delete(id); + reject(new Error("Worker response timeout")); + } + }, 20000); + + // Send the message to the worker + this.worker.postMessage(messageWithId); + }); } } exports.test = async function test(SQL, assert) { var target = process.argv[2]; var file = target ? "sql-" + target : "sql-wasm"; - if (file.indexOf('wasm') > -1 || file.indexOf('memory-growth') > -1) { + if (file.indexOf('memory-growth') > -1) { console.error("Skipping worker test for " + file + ". Not implemented yet"); return; }; - // If we use puppeteer, we need to pass in this new cwd as the root of the file being loaded: const filename = "../dist/worker." + file + ".js"; - var worker = await Worker.fromFile(path.join(__dirname, filename)); + var worker = await SQLWorker.fromFile(path.join(__dirname, filename)); var data = await worker.postMessage({ id: 1, action: 'open' }); assert.strictEqual(data.id, 1, "Return the given id in the correct format"); assert.deepEqual(data, { id: 1, ready: true }, 'Correct data answered to the "open" query'); @@ -148,5 +150,4 @@ if (module == require.main) { exports.test(null, assert).then(done); } }); - } From 1ae2bbed5d53829b4b10fa1206f009fdb79b3fb4 Mon Sep 17 00:00:00 2001 From: lovasoa Date: Fri, 14 Mar 2025 14:53:54 +0000 Subject: [PATCH 02/21] fix devcontainer by installing sha3sum --- .devcontainer/Dockerfile | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index e6b168d5..082d8418 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -68,4 +68,9 @@ RUN echo ". /emsdk/emsdk_env.sh" >> /etc/bash.bashrc RUN echo 'export EM_NODE_JS="$EMSDK_NODE"' >> /etc/bash.bashrc # END EMSDK -# -------------------------------------------------------------------- \ No newline at end of file +# -------------------------------------------------------------------- + +# Install wget, gnupg, and sha3sum +RUN apt-get update \ + && apt-get install -y wget gnupg libdigest-sha3-perl \ + && rm -rf /var/lib/apt/lists/* \ No newline at end of file From 8fa6fece479d8da0be1fb25409698c7022fdf14d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20S=C3=B6hnel?= Date: Fri, 14 Mar 2025 16:46:28 +0100 Subject: [PATCH 03/21] Add updateHook (#604) * Add updateHook A wrapper around sqlite3_update_hook. For now only as a low-level operation to Database. To be useful in projects it will probably need some wrapping in the worker but right now I have no idea yet how that should look. * Allow removing the updateHook callback Also release the callback function when the callback is removed or the database is closed. Include the previously omitted database name in the callback args as the sqlite callback does. --------- Co-authored-by: Erik Soehnel --- src/api.js | 97 +++++++++++++++++++++++++++++++++++++ src/exported_functions.json | 3 +- test/test_update_hook.js | 72 +++++++++++++++++++++++++++ 3 files changed, 171 insertions(+), 1 deletion(-) create mode 100644 test/test_update_hook.js diff --git a/src/api.js b/src/api.js index 10759d96..7ba821f8 100644 --- a/src/api.js +++ b/src/api.js @@ -71,6 +71,10 @@ Module["onRuntimeInitialized"] = function onRuntimeInitialized() { var SQLITE_BLOB = 4; // var - Encodings, used for registering functions. var SQLITE_UTF8 = 1; + // var - Authorizer Action Codes used to identify change types in updateHook + var SQLITE_INSERT = 18; + var SQLITE_UPDATE = 23; + var SQLITE_DELETE = 9; // var - cwrap function var sqlite3_open = cwrap("sqlite3_open", "number", ["string", "number"]); var sqlite3_close_v2 = cwrap("sqlite3_close_v2", "number", ["number"]); @@ -239,6 +243,12 @@ Module["onRuntimeInitialized"] = function onRuntimeInitialized() { ["number"] ); + var sqlite3_update_hook = cwrap( + "sqlite3_update_hook", + "number", + ["number", "number", "number"] + ); + /** * @classdesc * Represents a prepared statement. @@ -1114,6 +1124,12 @@ Module["onRuntimeInitialized"] = function onRuntimeInitialized() { }); Object.values(this.functions).forEach(removeFunction); this.functions = {}; + + if (this.updateHookFunctionPtr) { + removeFunction(this.updateHookFunctionPtr); + this.updateHookFunctionPtr = undefined; + } + this.handleError(sqlite3_close_v2(this.db)); FS.unlink("/" + this.filename); this.db = null; @@ -1383,6 +1399,87 @@ Module["onRuntimeInitialized"] = function onRuntimeInitialized() { return this; }; + /** Registers the update hook with SQLite + @param {function(operation, database, table, rowId) | null} callback + executed whenever a row in any rowid table is changed + + For each changed row, the callback is called once with the change + ('insert', 'update' or 'delete'), the database name and table name + where the change happened and the rowid of the row that has been + changed. + + rowid is cast to a plain number, if it exceeds Number.MAX_SAFE_INTEGER + an error will be thrown. + + The callback MUST NOT modify the database in any way. + + Only a single callback can be registered. Unregister the callback by + passing null. + + Not called for some updates like ON REPLACE CONFLICT and TRUNCATE (a + DELETE FROM without a WHERE clause). + + See sqlite docs on sqlite3_update_hook for more details. + */ + Database.prototype["updateHook"] = function updateHook(callback) { + if (this.updateHookFunctionPtr) { + // unregister and cleanup a previously registered update hook + sqlite3_update_hook(this.db, 0, 0); + removeFunction(this.updateHookFunctionPtr); + this.updateHookFunctionPtr = undefined; + } + + if (!callback) { + // no new callback to register + return; + } + + // void(*)(void *,int ,char const *,char const *,sqlite3_int64) + function wrappedCallback( + ignored, + operationCode, + databaseNamePtr, + tableNamePtr, + rowIdBigInt + ) { + var operation; + + switch (operationCode) { + case SQLITE_INSERT: + operation = "insert"; + break; + case SQLITE_UPDATE: + operation = "update"; + break; + case SQLITE_DELETE: + operation = "delete"; + break; + default: + throw "unknown operationCode in updateHook callback: " + + operationCode; + } + + var databaseName = UTF8ToString(databaseNamePtr); + var tableName = UTF8ToString(tableNamePtr); + + if (rowIdBigInt > Number.MAX_SAFE_INTEGER) { + throw "rowId too big to fit inside a Number"; + } + + var rowId = Number(rowIdBigInt); + + callback(operation, databaseName, tableName, rowId); + } + + this.updateHookFunctionPtr = addFunction(wrappedCallback, "viiiij"); + + sqlite3_update_hook( + this.db, + this.updateHookFunctionPtr, + 0 // passed as the first arg to wrappedCallback + ); + }; + // export Database to Module Module.Database = Database; }; diff --git a/src/exported_functions.json b/src/exported_functions.json index 324017ae..3be25955 100644 --- a/src/exported_functions.json +++ b/src/exported_functions.json @@ -42,5 +42,6 @@ "_sqlite3_result_int64", "_sqlite3_result_error", "_sqlite3_aggregate_context", -"_RegisterExtensionFunctions" +"_RegisterExtensionFunctions", +"_sqlite3_update_hook" ] diff --git a/test/test_update_hook.js b/test/test_update_hook.js new file mode 100644 index 00000000..ec875e25 --- /dev/null +++ b/test/test_update_hook.js @@ -0,0 +1,72 @@ +exports.test = function(SQL, assert){ + var db = new SQL.Database(); + + db.exec( + "CREATE TABLE consoles (id INTEGER PRIMARY KEY, company TEXT, name TEXT);" + + "INSERT INTO consoles VALUES (1, 'Sony', 'Playstation');" + + "INSERT INTO consoles VALUES (2, 'Microsoft', 'Xbox');" + ); + + // {operation: undefined, databaseName: undefined, tableName: undefined, rowId: undefined}; + var updateHookCalls = [] + + db.updateHook(function(operation, databaseName, tableName, rowId) { + updateHookCalls.push({operation, databaseName, tableName, rowId}); + }); + + // INSERT + db.exec("INSERT INTO consoles VALUES (3, 'Sega', 'Saturn');"); + + assert.deepEqual(updateHookCalls, [ + {operation: "insert", databaseName: "main", tableName: "consoles", rowId: 3} + ], "insert a single row"); + + // UPDATE + updateHookCalls = [] + db.exec("UPDATE consoles SET name = 'Playstation 5' WHERE id = 1"); + + assert.deepEqual(updateHookCalls, [ + {operation: "update", databaseName: "main", tableName: "consoles", rowId: 1} + ], "update a single row"); + + // UPDATE (multiple rows) + updateHookCalls = [] + db.exec("UPDATE consoles SET name = name + ' [legacy]' WHERE id IN (2,3)"); + + assert.deepEqual(updateHookCalls, [ + {operation: "update", databaseName: "main", tableName: "consoles", rowId: 2}, + {operation: "update", databaseName: "main", tableName: "consoles", rowId: 3}, + ], "update two rows"); + + // DELETE + updateHookCalls = [] + db.exec("DELETE FROM consoles WHERE company = 'Sega'"); + + assert.deepEqual(updateHookCalls, [ + {operation: "delete", databaseName: "main", tableName: "consoles", rowId: 3} + ], "delete a single row"); + + // UNREGISTER + updateHookCalls = [] + + db.updateHook(null); + + db.exec("DELETE FROM consoles WHERE company = 'Microsoft'"); + + assert.deepEqual(updateHookCalls, [], "unregister the update hook"); + + // REGISTER AGAIN + updateHookCalls = [] + + db.updateHook(function(operation, databaseName, tableName, rowId) { + updateHookCalls.push({operation, databaseName, tableName, rowId}); + }); + + // need a where clause, just running "DELETE FROM consoles" would result in + // a TRUNCATE and not yield any update hook callbacks + db.exec("DELETE FROM consoles WHERE id > 0"); + + assert.deepEqual(updateHookCalls, [ + {operation: 'delete', databaseName: 'main', tableName: 'consoles', rowId: 1} + ], "register the update hook again"); +} From c203d45a90e32b63b82a302629fbff633490859d Mon Sep 17 00:00:00 2001 From: lovasoa Date: Fri, 14 Mar 2025 15:51:25 +0000 Subject: [PATCH 04/21] add worker debug script --- test/test_workers.html | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 test/test_workers.html diff --git a/test/test_workers.html b/test/test_workers.html new file mode 100644 index 00000000..f0596a36 --- /dev/null +++ b/test/test_workers.html @@ -0,0 +1,23 @@ +

+

+ Run python -m http.server 2255, + then open this file. +

+ \ No newline at end of file From c35e16116c94688e739c1c9ab2c859b4f087837e Mon Sep 17 00:00:00 2001 From: lovasoa Date: Fri, 14 Mar 2025 15:51:37 +0000 Subject: [PATCH 05/21] v1.13 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1eb42f97..e3cdf1ab 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "sql.js", - "version": "1.12.0", + "version": "1.13.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "sql.js", - "version": "1.12.0", + "version": "1.13.0", "license": "MIT", "devDependencies": { "clean-jsdoc-theme": "^4.2.0", diff --git a/package.json b/package.json index e539e772..404fe3a9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sql.js", - "version": "1.12.0", + "version": "1.13.0", "description": "SQLite library with support for opening and writing databases, prepared statements, and more. This SQLite library is in pure javascript (compiled with emscripten).", "keywords": [ "sql", From 520fc61b46e4bbd6ead538800d3577292becb93d Mon Sep 17 00:00:00 2001 From: lovasoa Date: Sat, 15 Mar 2025 21:58:51 +0000 Subject: [PATCH 06/21] improve updateHook documentation --- package-lock.json | 26 +++++++------- src/api.js | 92 +++++++++++++++++++++++++++++++++++------------ 2 files changed, 84 insertions(+), 34 deletions(-) diff --git a/package-lock.json b/package-lock.json index e3cdf1ab..0ebce1ef 100644 --- a/package-lock.json +++ b/package-lock.json @@ -450,18 +450,19 @@ } }, "node_modules/array.prototype.findlastindex": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", - "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz", + "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", + "es-abstract": "^1.23.9", "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-shim-unscopables": "^1.0.2" + "es-object-atoms": "^1.1.1", + "es-shim-unscopables": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -2645,15 +2646,16 @@ } }, "node_modules/object.entries": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", - "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz", + "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" + "es-object-atoms": "^1.1.1" }, "engines": { "node": ">= 0.4" diff --git a/src/api.js b/src/api.js index 7ba821f8..e1d75dfb 100644 --- a/src/api.js +++ b/src/api.js @@ -1399,28 +1399,76 @@ Module["onRuntimeInitialized"] = function onRuntimeInitialized() { return this; }; - /** Registers the update hook with SQLite - @param {function(operation, database, table, rowId) | null} callback - executed whenever a row in any rowid table is changed - - For each changed row, the callback is called once with the change - ('insert', 'update' or 'delete'), the database name and table name - where the change happened and the rowid of the row that has been - changed. - - rowid is cast to a plain number, if it exceeds Number.MAX_SAFE_INTEGER - an error will be thrown. - - The callback MUST NOT modify the database in any way. - - Only a single callback can be registered. Unregister the callback by - passing null. - - Not called for some updates like ON REPLACE CONFLICT and TRUNCATE (a - DELETE FROM without a WHERE clause). - - See sqlite docs on sqlite3_update_hook for more details. - */ + /** Registers an update hook with SQLite. + * + * Every time a row is changed by whatever means, the callback is called + * once with the change (`'insert'`, `'update'` or `'delete'`), the database + * name and table name where the change happened and the + * [rowid](https://www.sqlite.org/rowidtable.html) + * of the row that has been changed. + * + * The rowid is cast to a plain number. If it exceeds + * `Number.MAX_SAFE_INTEGER` (2^53 - 1), an error will be thrown. + * + * **Important notes:** + * - The callback **MUST NOT** modify the database in any way + * - Only a single callback can be registered at a time + * - Unregister the callback by passing `null` + * - Not called for some updates like `ON REPLACE CONFLICT` and `TRUNCATE` + * (a `DELETE FROM` without a `WHERE` clause) + * + * See SQLite documentation on + * [sqlite3_update_hook](https://www.sqlite.org/c3ref/update_hook.html) + * for more details + * + * @example + * // Create a database and table + * var db = new SQL.Database(); + * db.exec(` + * CREATE TABLE users ( + * id INTEGER PRIMARY KEY, -- this is the rowid column + * name TEXT, + * active INTEGER + * ) + * `); + * + * // Register an update hook + * var changes = []; + * db.updateHook(function(operation, database, table, rowId) { + * changes.push({operation, database, table, rowId}); + * console.log(`${operation} on ${database}.${table} row ${rowId}`); + * }); + * + * // Insert a row - triggers the update hook with 'insert' + * db.run("INSERT INTO users VALUES (1, 'Alice', 1)"); + * // Logs: "insert on main.users row 1" + * + * // Update a row - triggers the update hook with 'update' + * db.run("UPDATE users SET active = 0 WHERE id = 1"); + * // Logs: "update on main.users row 1" + * + * // Delete a row - triggers the update hook with 'delete' + * db.run("DELETE FROM users WHERE id = 1"); + * // Logs: "delete on main.users row 1" + * + * // Unregister the update hook + * db.updateHook(null); + * + * // This won't trigger any callback + * db.run("INSERT INTO users VALUES (2, 'Bob', 1)"); + * + * @param {function|null} callback - + * Callback to be executed whenever a row changes. + * Set to `null` to unregister the callback. + * @param {string} callback.operation - + * 'insert', 'update', or 'delete' + * @param {string} callback.database - + * database where the change occurred + * @param {string} callback.table - + * table where the change occurred + * @param {number} callback.rowId - + * rowid of the changed row + */ Database.prototype["updateHook"] = function updateHook(callback) { if (this.updateHookFunctionPtr) { // unregister and cleanup a previously registered update hook From 739fb7826a5b3aaff3fd47ce8431405aa50c3f82 Mon Sep 17 00:00:00 2001 From: lovasoa Date: Sat, 15 Mar 2025 22:15:54 +0000 Subject: [PATCH 07/21] improve demo gui --- examples/GUI/demo.css | 547 +++++++++++++++++++++++++++++++++++---- examples/GUI/gui.js | 561 ++++++++++++++++++++++++++++++++++++++-- examples/GUI/index.html | 132 +++++++--- 3 files changed, 1138 insertions(+), 102 deletions(-) diff --git a/examples/GUI/demo.css b/examples/GUI/demo.css index 00e2bc6d..38f28fc3 100644 --- a/examples/GUI/demo.css +++ b/examples/GUI/demo.css @@ -1,82 +1,535 @@ +:root { + --bg-dark: #0f1923; + --bg-panel: #1a2634; + --bg-panel-lighter: #1e2c3a; + --text-primary: #e9ecef; + --text-secondary: rgba(255, 255, 255, 0.7); + --text-muted: rgba(255, 255, 255, 0.4); + --accent-blue: #4fbeff; + --accent-green: #2b6a4a; + --border-subtle: rgba(255, 255, 255, 0.1); + --shadow-inset: 0 2px 10px rgba(0, 0, 0, 0.2) inset, 0 1px 0 rgba(255, 255, 255, 0.05); + --shadow-subtle: 0 4px 15px rgba(0, 0, 0, 0.1); + --shadow-strong: 0 10px 30px rgba(0, 0, 0, 0.5); + --radius-sm: 6px; + --radius-md: 8px; + --radius-lg: 12px; + --transition-normal: all 0.2s ease; +} + html { - background:#222; - margin:auto; - width:80%; + background: var(--bg-dark); + margin: 0; + padding: 0; + width: 100%; + height: 100%; + font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif; + color: var(--text-primary); } -body{ - background: linear-gradient(#aaa 0, #ddd 10px, #fff 55px); - border: 1px solid black; - padding: 10px 20px; - box-shadow: 5px 0px 30px #000; - border-radius: 8px; +body { + background: linear-gradient(145deg, var(--bg-panel) 0%, #131e2b 100%); + border: none; + margin: 0; + padding: 0; + width: 100%; + height: 100vh; + display: flex; + flex-direction: column; + overflow: hidden; +} + +header { + padding: 15px 20px; + border-bottom: 1px solid var(--border-subtle); + display: flex; + align-items: center; + justify-content: space-between; + background: rgba(15, 25, 35, 0.4); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2); + z-index: 10; } h1 { - text-align: center; - color: #222; - margin: 0 0 30px; + font-size: 1.5rem; + margin: 0; + font-weight: 600; + letter-spacing: -0.5px; + text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3); +} + +.app-container { + display: flex; + flex: 1; + overflow: hidden; + position: relative; +} + +.toolbar { + display: flex; + align-items: center; + gap: 10px; } .button { - color: #333; - background: linear-gradient(#eee, #ddd); - border: 1px solid #222; - border-radius: 3px; - padding: 7px; - margin-right: 5px; - transition: .3s; - font-family: ubuntu, sans-serif; - font-size: 1em; + color: var(--text-primary); + background: linear-gradient(145deg, var(--bg-panel-lighter) 0%, #162330 100%); + border: 1px solid var(--border-subtle); + border-radius: var(--radius-sm); + padding: 8px 14px; + transition: var(--transition-normal); + font-family: inherit; + font-size: 0.9em; + font-weight: 500; + cursor: pointer; + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2), 0 1px 0 rgba(255, 255, 255, 0.05) inset; + display: flex; + align-items: center; + gap: 6px; } .button:active { - background: linear-gradient(#ddd, #eee); + background: linear-gradient(145deg, #162330 0%, var(--bg-panel-lighter) 100%); + transform: translateY(1px); + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3) inset; +} + +.button:hover, .button:focus { + box-shadow: 0 0 0 2px rgba(79, 190, 255, 0.3), 0 1px 0 rgba(255, 255, 255, 0.05) inset; + outline: none; +} + +.button svg { + width: 16px; + height: 16px; +} + +.button-primary { + background: linear-gradient(145deg, #2b5d8b 0%, #1e4266 100%); +} + +.button-primary:hover { + background: linear-gradient(145deg, #306ca3 0%, #1e4266 100%); +} + +.button-success { + background: linear-gradient(145deg, #2b6a4a 0%, #1e4a33 100%); +} + +.button-success:hover { + background: linear-gradient(145deg, #307a55 0%, #1e4a33 100%); +} + +label.button { + display: inline-flex; +} + +input[type="file"] { + display: none; +} + +.panel { + display: flex; + flex-direction: column; + overflow: hidden; + position: relative; +} + +.panel-resizable { + flex: 1; + min-width: 300px; + max-width: calc(100% - 300px); + position: relative; +} + +.editor-panel { + border-right: 1px solid var(--border-subtle); } -.button:hover, button:focus { - box-shadow: 0 0 2px #222; +.results-panel { + flex: 1; + display: flex; + flex-direction: column; } -#execute { - margin-top: 5px;; - width: 10%; - min-width:100px; +.panel-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 10px 15px; + background: rgba(15, 25, 35, 0.4); + border-bottom: 1px solid var(--border-subtle); + font-weight: 500; + color: var(--text-secondary); +} + +.panel-content { + flex: 1; + overflow: auto; + position: relative; } .CodeMirror { - border: 1px solid #222; - height: auto; + border: none; + height: 100% !important; + background: rgba(15, 25, 35, 0.6); + box-shadow: var(--shadow-inset); + font-family: 'JetBrains Mono', 'Fira Code', monospace; + font-size: 14px; +} + +.CodeMirror-gutters { + background: rgba(15, 25, 35, 0.8); + border-right: 1px solid var(--border-subtle); } -.CodeMirror-scroll { - overflow-y: hidden; - overflow-x: auto; + +.CodeMirror-linenumber { + color: var(--text-muted); } .error { - color:red; - transition:.5s; - overflow:hidden; - margin: 15px; + color: #ff6b6b; + transition: .3s; + overflow: hidden; + padding: 10px 15px; + border-radius: var(--radius-sm); + background: rgba(255, 0, 0, 0.1); + border-left: 3px solid #ff6b6b; + margin: 10px; + opacity: 0; + height: 0; +} + +.results-tabs { + display: flex; + background: rgba(15, 25, 35, 0.4); + border-bottom: 1px solid var(--border-subtle); + overflow-x: auto; + scrollbar-width: thin; +} + +.tab { + padding: 8px 16px; + background: transparent; + border: none; + border-right: 1px solid var(--border-subtle); + color: var(--text-secondary); + cursor: pointer; + white-space: nowrap; + transition: var(--transition-normal); + font-family: inherit; + font-size: 0.9em; +} + +.tab.active { + background: rgba(79, 190, 255, 0.1); + color: var(--accent-blue); + font-weight: 500; +} + +.tab:hover:not(.active) { + background: rgba(255, 255, 255, 0.05); +} + +.tab-close { + margin-left: 8px; + opacity: 0.6; + transition: var(--transition-normal); +} + +.tab:hover .tab-close { + opacity: 1; +} + +.results-content { + flex: 1; + overflow: auto; + padding: 15px; + background: rgba(15, 25, 35, 0.4); + box-shadow: var(--shadow-inset); } -#output { +.tab-panel { + display: none; + height: 100%; overflow: auto; } +.tab-panel.active { + display: block; +} + +.resizer { + width: 6px; + cursor: col-resize; + background: transparent; + position: absolute; + top: 0; + right: -3px; + bottom: 0; + z-index: 10; + transition: background 0.2s; +} + +.resizer:hover, .resizer.active { + background: rgba(79, 190, 255, 0.3); +} + table { - width:auto; - margin:auto; - border:1px solid black; - border-collapse:collapse; - margin-bottom:10px; + width: 100%; + margin: 0 0 20px 0; + border: 1px solid var(--border-subtle); + border-collapse: collapse; + border-radius: var(--radius-sm); + overflow: hidden; + box-shadow: var(--shadow-subtle); + background: rgba(30, 40, 50, 0.4); +} + +thead { + background: rgba(40, 60, 80, 0.6); + position: sticky; + top: 0; + z-index: 1; +} + +th { + text-align: left; + padding: 12px 15px; + font-weight: 600; + color: var(--accent-blue); + border-bottom: 1px solid var(--border-subtle); } -th, td { - border:1px solid #777; +td { + padding: 10px 15px; + border-bottom: 1px solid rgba(255, 255, 255, 0.05); +} + +tr:last-child td { + border-bottom: none; +} + +tr:nth-child(even) { + background: rgba(255, 255, 255, 0.03); +} + +.table-wrapper { + margin-bottom: 20px; +} + +.table-caption { + color: var(--text-secondary); + font-size: 0.85em; + margin-bottom: 8px; + display: flex; + justify-content: space-between; + align-items: center; +} + +.loading { + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; + height: 100%; + color: var(--text-secondary); +} + +.spinner { + width: 30px; + height: 30px; + border: 3px solid rgba(79, 190, 255, 0.3); + border-radius: 50%; + border-top-color: var(--accent-blue); + animation: spin 1s ease-in-out infinite; + margin-bottom: 15px; +} + +@keyframes spin { + to { transform: rotate(360deg); } +} + +.no-results { + color: var(--text-muted); + text-align: center; + padding: 30px; +} + +.notification { + position: fixed; + bottom: -60px; + left: 50%; + transform: translateX(-50%); + background: rgba(40, 60, 80, 0.9); + color: #fff; + padding: 12px 20px; + border-radius: var(--radius-md); + box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3); + transition: bottom 0.3s ease; + z-index: 1000; + border-left: 3px solid var(--accent-blue); +} + +.notification.show { + bottom: 20px; +} + +.button.active { + transform: translateY(1px); + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3) inset; +} + +.status-bar { + display: flex; + justify-content: space-between; + align-items: center; + padding: 6px 15px; + background: rgba(15, 25, 35, 0.8); + border-top: 1px solid var(--border-subtle); + font-size: 0.8em; + color: var(--text-secondary); +} + +.status-item { + display: flex; + align-items: center; + gap: 6px; +} + +.status-success { + color: #4ade80; +} + +.status-error { + color: #ff6b6b; +} + +.status-info { + color: var(--accent-blue); +} + +.shortcuts { + display: flex; + align-items: center; + gap: 10px; +} + +.shortcut-key { + background: rgba(255, 255, 255, 0.1); + padding: 2px 6px; + border-radius: 3px; + font-family: 'JetBrains Mono', monospace; + font-size: 0.85em; } footer { - font-size:.8em; - color: #222; + font-size: 0.8em; + color: var(--text-muted); + text-align: center; + padding: 10px; + background: rgba(15, 25, 35, 0.8); + border-top: 1px solid var(--border-subtle); +} + +footer a { + color: var(--accent-blue); + text-decoration: none; +} + +footer a:hover { + text-decoration: underline; +} + +.query-history { + position: absolute; + top: 100%; + left: 0; + right: 0; + background: rgba(30, 40, 50, 0.95); + border-top: 1px solid var(--border-subtle); + max-height: 0; + overflow: hidden; + transition: max-height 0.3s ease; + z-index: 100; + box-shadow: var(--shadow-strong); +} + +.query-history.show { + max-height: 300px; + overflow-y: auto; +} + +.history-item { + padding: 8px 15px; + border-bottom: 1px solid var(--border-subtle); + cursor: pointer; + transition: var(--transition-normal); + display: flex; + justify-content: space-between; + align-items: center; +} + +.history-item:hover { + background: rgba(255, 255, 255, 0.05); +} + +.history-query { + font-family: 'JetBrains Mono', monospace; + font-size: 0.85em; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + max-width: 80%; +} + +.history-time { + color: var(--text-muted); + font-size: 0.8em; +} + +::-webkit-scrollbar { + width: 8px; + height: 8px; +} + +::-webkit-scrollbar-track { + background: rgba(0, 0, 0, 0.1); + border-radius: 4px; +} + +::-webkit-scrollbar-thumb { + background: rgba(255, 255, 255, 0.1); + border-radius: 4px; +} + +::-webkit-scrollbar-thumb:hover { + background: rgba(255, 255, 255, 0.2); +} + +@media (max-width: 768px) { + .app-container { + flex-direction: column; + } + + .panel-resizable { + max-width: 100%; + height: 50%; + min-height: 200px; + max-height: calc(100% - 200px); + } + + .editor-panel { + border-right: none; + border-bottom: 1px solid var(--border-subtle); + } + + .resizer { + width: 100%; + height: 6px; + cursor: row-resize; + right: 0; + bottom: -3px; + top: auto; + } } diff --git a/examples/GUI/gui.js b/examples/GUI/gui.js index df499ab3..e57c83ee 100644 --- a/examples/GUI/gui.js +++ b/examples/GUI/gui.js @@ -1,51 +1,130 @@ -var execBtn = document.getElementById("execute"); -var outputElm = document.getElementById('output'); -var errorElm = document.getElementById('error'); -var commandsElm = document.getElementById('commands'); -var dbFileElm = document.getElementById('dbfile'); -var savedbElm = document.getElementById('savedb'); +// DOM Elements +const execBtn = document.getElementById("execute"); +const outputElm = document.getElementById('output'); +const errorElm = document.getElementById('error'); +const commandsElm = document.getElementById('commands'); +const dbFileElm = document.getElementById('dbfile'); +const savedbElm = document.getElementById('savedb'); +const editorStatusElm = document.getElementById('editorStatus'); +const resultsStatusElm = document.getElementById('resultsStatus'); +const queryTimeElm = document.getElementById('queryTime'); +const panelResizerElm = document.getElementById('panelResizer'); +const queryHistoryElm = document.getElementById('queryHistory'); +const toggleHistoryBtn = document.getElementById('toggleHistory'); +const resultsTabs = document.getElementById('resultsTabs'); +const newTabBtn = document.getElementById('newTabBtn'); + +// State +let currentTabId = 'tab1'; +let tabCounter = 1; +let queryHistory = []; +let isResizing = false; +let lastExecutionTime = 0; // Start the worker in which sql.js will run -var worker = new Worker("../../dist/worker.sql-wasm.js"); +const worker = new Worker("../../dist/worker.sql-wasm.js"); worker.onerror = error; // Open a database worker.postMessage({ action: 'open' }); -// Connect to the HTML element we 'print' to -function print(text) { - outputElm.innerHTML = text.replace(/\n/g, '
'); -} +// Initialize resizable panels +initResizer(); + +// Initialize tabs +initTabs(); + +// Error handling function error(e) { console.log(e); - errorElm.style.height = '2em'; + errorElm.style.height = 'auto'; errorElm.textContent = e.message; + errorElm.style.opacity = 1; + + updateStatus('error', `Error: ${e.message}`); + + setTimeout(() => { + errorElm.style.opacity = 0; + setTimeout(() => { + errorElm.style.height = '0'; + }, 300); + }, 5000); } function noerror() { errorElm.style.height = '0'; + errorElm.style.opacity = 0; +} + +// Status updates +function updateStatus(type, message) { + switch(type) { + case 'executing': + editorStatusElm.innerHTML = `Executing query...`; + resultsStatusElm.innerHTML = `Executing query...`; + break; + case 'success': + editorStatusElm.innerHTML = `Query executed successfully`; + resultsStatusElm.innerHTML = `${message}`; + break; + case 'error': + editorStatusElm.innerHTML = `Query failed`; + resultsStatusElm.innerHTML = `${message}`; + break; + default: + editorStatusElm.textContent = message; + break; + } +} + +function updateQueryTime(time) { + queryTimeElm.textContent = `Execution time: ${time.toFixed(2)}ms`; + lastExecutionTime = time; } // Run a command in the database -function execute(commands) { +function execute(commands, tabId = currentTabId) { tic(); + updateStatus('executing'); + + // Get the output element for the current tab + const tabOutputElm = document.querySelector(`#${tabId} .results-content`); + if (!tabOutputElm) return; + + // Show loading indicator + tabOutputElm.innerHTML = '
Executing query...
'; + + // Add to query history + addToHistory(commands); + worker.onmessage = function (event) { - var results = event.data.results; - toc("Executing SQL"); + const results = event.data.results; + const executionTime = toc("Executing SQL"); + if (!results) { error({message: event.data.error}); return; } tic(); - outputElm.innerHTML = ""; + tabOutputElm.innerHTML = ""; + + if (results.length === 0) { + tabOutputElm.innerHTML = '
Query executed successfully. No results to display.
'; + updateStatus('success', 'Query executed with no results'); + return; + } + for (var i = 0; i < results.length; i++) { - outputElm.appendChild(tableCreate(results[i].columns, results[i].values)); + tabOutputElm.appendChild(tableCreate(results[i].columns, results[i].values)); } - toc("Displaying results"); + + const displayTime = toc("Displaying results"); + updateQueryTime(executionTime + displayTime); + updateStatus('success', `Returned ${results.length} result set${results.length !== 1 ? 's' : ''}`); } + worker.postMessage({ action: 'exec', sql: commands }); - outputElm.textContent = "Fetching results..."; } // Create an HTML table @@ -58,19 +137,51 @@ var tableCreate = function () { return function (columns, values) { var tbl = document.createElement('table'); var html = '' + valconcat(columns, 'th') + ''; - var rows = values.map(function (v) { return valconcat(v, 'td'); }); - html += '' + valconcat(rows, 'tr') + ''; + + if (values.length === 0) { + html += 'No results'; + } else { + var rows = values.map(function (v) { return valconcat(v, 'td'); }); + html += '' + valconcat(rows, 'tr') + ''; + } + tbl.innerHTML = html; - return tbl; + + // Add a wrapper with a caption showing the number of rows + var wrapper = document.createElement('div'); + wrapper.className = 'table-wrapper'; + var caption = document.createElement('div'); + caption.className = 'table-caption'; + caption.innerHTML = ` + ${values.length} row${values.length !== 1 ? 's' : ''} + ${columns.length} column${columns.length !== 1 ? 's' : ''} + `; + wrapper.appendChild(caption); + wrapper.appendChild(tbl); + + return wrapper; } }(); // Execute the commands when the button is clicked function execEditorContents() { - noerror() + noerror(); + + // Create a new tab if needed + if (document.querySelectorAll('.results-tabs .tab').length <= 2) { // Only the first tab and + button + createNewTab(); + } + execute(editor.getValue() + ';'); + + // Add visual feedback for button click + execBtn.classList.add('active'); + setTimeout(() => { + execBtn.classList.remove('active'); + }, 200); } -execBtn.addEventListener("click", execEditorContents, true); + +execBtn.addEventListener("click", execEditorContents); // Performance measurement functions var tictime; @@ -79,9 +190,10 @@ function tic() { tictime = performance.now() } function toc(msg) { var dt = performance.now() - tictime; console.log((msg || 'toc') + ": " + dt + "ms"); + return dt; } -// Add syntax highlihjting to the textarea +// Add syntax highlighting to the textarea var editor = CodeMirror.fromTextArea(commandsElm, { mode: 'text/x-mysql', viewportMargin: Infinity, @@ -90,9 +202,13 @@ var editor = CodeMirror.fromTextArea(commandsElm, { lineNumbers: true, matchBrackets: true, autofocus: true, + theme: 'nord', extraKeys: { "Ctrl-Enter": execEditorContents, + "Cmd-Enter": execEditorContents, "Ctrl-S": savedb, + "Cmd-S": savedb, + "Ctrl-Space": toggleQueryHistory, } }); @@ -105,7 +221,14 @@ dbFileElm.onchange = function () { toc("Loading database from file"); // Show the schema of the loaded database editor.setValue("SELECT `name`, `sql`\n FROM `sqlite_master`\n WHERE type='table';"); + + // Create a new tab for the results + createNewTab(); execEditorContents(); + + // Show success notification + showNotification('Database loaded successfully'); + updateStatus('success', 'Database loaded successfully'); }; tic(); try { @@ -120,6 +243,8 @@ dbFileElm.onchange = function () { // Save the db to a file function savedb() { + updateStatus('info', 'Saving database...'); + worker.onmessage = function (event) { toc("Exporting the database"); var arraybuff = event.data.buffer; @@ -134,8 +259,392 @@ function savedb() { }, 1500); }; a.click(); + + // Show success notification + showNotification('Database saved successfully'); + updateStatus('success', 'Database saved successfully'); + + // Add visual feedback for button click + savedbElm.classList.add('active'); + setTimeout(() => { + savedbElm.classList.remove('active'); + }, 200); }; tic(); worker.postMessage({ action: 'export' }); } -savedbElm.addEventListener("click", savedb, true); +savedbElm.addEventListener("click", savedb); + +// Create a notification system +function showNotification(message) { + // Create notification element if it doesn't exist + let notification = document.querySelector('.notification'); + if (!notification) { + notification = document.createElement('div'); + notification.className = 'notification'; + document.body.appendChild(notification); + } + + // Set message and show + notification.textContent = message; + notification.classList.add('show'); + + // Hide after 3 seconds + setTimeout(() => { + notification.classList.remove('show'); + }, 3000); +} + +// Initialize resizable panels +function initResizer() { + const editorPanel = document.querySelector('.editor-panel'); + + panelResizerElm.addEventListener('mousedown', function(e) { + isResizing = true; + document.body.classList.add('resizing'); + panelResizerElm.classList.add('active'); + }); + + document.addEventListener('mousemove', function(e) { + if (!isResizing) return; + + const containerWidth = document.querySelector('.app-container').offsetWidth; + let newWidth; + + // Check if we're in mobile view (flexbox column) + const isMobileView = window.getComputedStyle(document.querySelector('.app-container')).flexDirection === 'column'; + + if (isMobileView) { + // In mobile view, resize height instead of width + const containerHeight = document.querySelector('.app-container').offsetHeight; + const newHeight = e.clientY - editorPanel.getBoundingClientRect().top; + const minHeight = 100; + const maxHeight = containerHeight - 100; + + editorPanel.style.height = `${Math.min(Math.max(newHeight, minHeight), maxHeight)}px`; + } else { + // Desktop view - resize width + newWidth = e.clientX - editorPanel.getBoundingClientRect().left; + const minWidth = 200; + const maxWidth = containerWidth - 200; + + editorPanel.style.width = `${Math.min(Math.max(newWidth, minWidth), maxWidth)}px`; + } + + e.preventDefault(); + }); + + document.addEventListener('mouseup', function() { + if (isResizing) { + isResizing = false; + document.body.classList.remove('resizing'); + panelResizerElm.classList.remove('active'); + } + }); +} + +// Initialize tabs +function initTabs() { + // New tab button + newTabBtn.addEventListener('click', createNewTab); + + // Tab click handler + resultsTabs.addEventListener('click', function(e) { + const target = e.target; + + // Handle tab close button + if (target.classList.contains('tab-close')) { + const tabId = target.parentElement.dataset.tab; + closeTab(tabId); + e.stopPropagation(); + return; + } + + // Handle tab selection + if (target.classList.contains('tab') && !target.id) { + const tabId = target.dataset.tab; + if (tabId) { + setActiveTab(tabId); + } + } + }); +} + +// Create a new results tab +function createNewTab() { + tabCounter++; + const tabId = `tab${tabCounter}`; + + // Create tab button + const tab = document.createElement('button'); + tab.className = 'tab'; + tab.dataset.tab = tabId; + tab.innerHTML = `Result ${tabCounter} ×`; + + // Insert before the + button + resultsTabs.insertBefore(tab, newTabBtn); + + // Create tab panel + const tabPanel = document.createElement('div'); + tabPanel.className = 'tab-panel'; + tabPanel.id = tabId; + + // Create results content container + const resultsContent = document.createElement('div'); + resultsContent.className = 'results-content'; + resultsContent.textContent = 'Execute a query to see results'; + + tabPanel.appendChild(resultsContent); + document.querySelector('.results-panel .panel-content').appendChild(tabPanel); + + // Set as active + setActiveTab(tabId); + + return tabId; +} + +// Set active tab +function setActiveTab(tabId) { + // Update current tab id + currentTabId = tabId; + + // Update tab buttons + document.querySelectorAll('.results-tabs .tab').forEach(tab => { + tab.classList.remove('active'); + if (tab.dataset.tab === tabId) { + tab.classList.add('active'); + } + }); + + // Update tab panels + document.querySelectorAll('.tab-panel').forEach(panel => { + panel.classList.remove('active'); + if (panel.id === tabId) { + panel.classList.add('active'); + } + }); +} + +// Close a tab +function closeTab(tabId) { + // Don't close if it's the last content tab + const contentTabs = document.querySelectorAll('.results-tabs .tab:not(#newTabBtn)'); + if (contentTabs.length <= 1) { + return; + } + + // Remove tab button + const tab = document.querySelector(`.tab[data-tab="${tabId}"]`); + if (tab) { + tab.remove(); + } + + // Remove tab panel + const panel = document.getElementById(tabId); + if (panel) { + panel.remove(); + } + + // If we closed the active tab, activate another one + if (currentTabId === tabId) { + const firstTab = document.querySelector('.results-tabs .tab:not(#newTabBtn)'); + if (firstTab) { + setActiveTab(firstTab.dataset.tab); + } + } +} + +// Query history functions +function addToHistory(query) { + // Limit history size + if (queryHistory.length >= 20) { + queryHistory.pop(); + } + + // Add to beginning of array + queryHistory.unshift({ + query: query, + timestamp: new Date(), + executionTime: lastExecutionTime + }); + + // Update history UI + updateHistoryUI(); +} + +function updateHistoryUI() { + queryHistoryElm.innerHTML = ''; + + queryHistory.forEach((item, index) => { + const historyItem = document.createElement('div'); + historyItem.className = 'history-item'; + + // Format timestamp + const timestamp = item.timestamp; + const timeString = timestamp.toLocaleTimeString(); + + // Truncate query if too long + const queryPreview = item.query.length > 60 ? + item.query.substring(0, 60) + '...' : + item.query; + + historyItem.innerHTML = ` +
${queryPreview}
+
${timeString}
+ `; + + // Add click handler to load query + historyItem.addEventListener('click', () => { + editor.setValue(item.query); + toggleQueryHistory(); + }); + + queryHistoryElm.appendChild(historyItem); + }); +} + +function toggleQueryHistory() { + queryHistoryElm.classList.toggle('show'); +} + +// Toggle history button +toggleHistoryBtn.addEventListener('click', toggleQueryHistory); + +// Close history when clicking outside +document.addEventListener('click', function(e) { + if (queryHistoryElm.classList.contains('show') && + !queryHistoryElm.contains(e.target) && + e.target !== toggleHistoryBtn) { + queryHistoryElm.classList.remove('show'); + } +}); + +// Initial status +updateStatus('info', 'Ready'); + +// Handle window resize +window.addEventListener('resize', function() { + // Reset any explicit dimensions on mobile/desktop switch + const isMobileView = window.innerWidth <= 768; + const editorPanel = document.querySelector('.editor-panel'); + + if (isMobileView) { + editorPanel.style.width = ''; + } else { + editorPanel.style.height = ''; + } +}); + +// Add CSS for new elements +const style = document.createElement('style'); +style.textContent = ` +.loading { + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; + height: 100px; + color: rgba(255, 255, 255, 0.7); +} + +.spinner { + width: 30px; + height: 30px; + border: 3px solid rgba(79, 190, 255, 0.3); + border-radius: 50%; + border-top-color: #4fbeff; + animation: spin 1s ease-in-out infinite; + margin-bottom: 15px; +} + +@keyframes spin { + to { transform: rotate(360deg); } +} + +.table-wrapper { + margin-bottom: 20px; +} + +.table-caption { + color: rgba(255, 255, 255, 0.6); + font-size: 0.85em; + margin-bottom: 8px; + text-align: right; +} + +.no-results { + color: rgba(255, 255, 255, 0.5); + text-align: center; + padding: 30px; +} + +.notification { + position: fixed; + bottom: -60px; + left: 50%; + transform: translateX(-50%); + background: rgba(40, 60, 80, 0.9); + color: #fff; + padding: 12px 20px; + border-radius: 8px; + box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3); + transition: bottom 0.3s ease; + z-index: 1000; + border-left: 3px solid #4fbeff; +} + +.notification.show { + bottom: 20px; +} + +.button.active { + transform: translateY(1px); + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3) inset; +} + +.results-header, .editor-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 8px; + color: rgba(255, 255, 255, 0.7); + font-weight: 500; +} + +.actions { + display: flex; + flex-wrap: wrap; + margin: 15px 0; +} + +.github-corner:hover .octo-arm { + animation: octocat-wave 560ms ease-in-out; +} + +@keyframes octocat-wave { + 0%, 100% { transform: rotate(0); } + 20%, 60% { transform: rotate(-25deg); } + 40%, 80% { transform: rotate(10deg); } +} + +@media (max-width: 500px) { + .github-corner:hover .octo-arm { + animation: none; + } + .github-corner .octo-arm { + animation: octocat-wave 560ms ease-in-out; + } +} +`; +document.head.appendChild(style); + +// Add keyboard shortcuts info +document.addEventListener('DOMContentLoaded', function() { + const editorHeader = document.querySelector('.editor-header'); + if (editorHeader) { + const shortcuts = document.createElement('div'); + shortcuts.className = 'shortcuts'; + shortcuts.innerHTML = 'Keyboard shortcuts'; + editorHeader.appendChild(shortcuts); + } +}); diff --git a/examples/GUI/index.html b/examples/GUI/index.html index 747fe4f4..19f53249 100644 --- a/examples/GUI/index.html +++ b/examples/GUI/index.html @@ -1,29 +1,69 @@ - + - - Codestin Search App + + + Codestin Search App + + + + - - - Fork me on GitHub - -

Online SQL interpreter

- -
- -
+
+

SQL.js Interpreter

+
+ + + + +
+
- +
+ +
+ +
+
+ Ready +
+
+
+ - - - - -
- -
Results will be displayed here
-
- - + +
+
+ + +
+
+
+
+
Results will be displayed here
+
+
+
+
+ No query executed yet +
+
+ +
+
+
+ + + + + + + From 3536f9d79c414dd08e9c367daad370e6efc5212f Mon Sep 17 00:00:00 2001 From: lovasoa Date: Sat, 15 Mar 2025 22:23:03 +0000 Subject: [PATCH 08/21] no inline css in js --- examples/GUI/demo.css | 66 +++++++++++++++++ examples/GUI/gui.js | 152 ++++++++++++---------------------------- examples/GUI/index.html | 11 +-- 3 files changed, 114 insertions(+), 115 deletions(-) diff --git a/examples/GUI/demo.css b/examples/GUI/demo.css index 38f28fc3..bd366f7a 100644 --- a/examples/GUI/demo.css +++ b/examples/GUI/demo.css @@ -413,6 +413,14 @@ tr:nth-child(even) { display: flex; align-items: center; gap: 10px; + margin-left: auto; +} + +.shortcuts span { + display: flex; + align-items: center; + margin-left: 8px; + color: var(--text-muted); } .shortcut-key { @@ -421,6 +429,8 @@ tr:nth-child(even) { border-radius: 3px; font-family: 'JetBrains Mono', monospace; font-size: 0.85em; + margin-left: 4px; + color: var(--text-secondary); } footer { @@ -514,6 +524,7 @@ footer a:hover { .panel-resizable { max-width: 100%; + width: 100% !important; height: 50%; min-height: 200px; max-height: calc(100% - 200px); @@ -532,4 +543,59 @@ footer a:hover { bottom: -3px; top: auto; } + + .shortcuts { + display: none; + } +} + +body.resizing { + cursor: col-resize; + user-select: none; +} + +@media (max-width: 768px) { + body.resizing { + cursor: row-resize; + } +} + +.error-result { + color: #ff6b6b; + border-left: 3px solid #ff6b6b; + background: rgba(255, 0, 0, 0.05); +} + +.github-corner:hover .octo-arm { + animation: octocat-wave 560ms ease-in-out; +} + +@keyframes octocat-wave { + 0%, 100% { transform: rotate(0); } + 20%, 60% { transform: rotate(-25deg); } + 40%, 80% { transform: rotate(10deg); } +} + +@media (max-width: 500px) { + .github-corner:hover .octo-arm { + animation: none; + } + .github-corner .octo-arm { + animation: octocat-wave 560ms ease-in-out; + } +} + +.actions { + display: flex; + flex-wrap: wrap; + margin: 15px 0; +} + +.results-header, .editor-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 8px; + color: rgba(255, 255, 255, 0.7); + font-weight: 500; } diff --git a/examples/GUI/gui.js b/examples/GUI/gui.js index e57c83ee..c761cee3 100644 --- a/examples/GUI/gui.js +++ b/examples/GUI/gui.js @@ -43,6 +43,12 @@ function error(e) { updateStatus('error', `Error: ${e.message}`); + // Clear loading spinner in the current tab when an error occurs + const tabOutputElm = document.querySelector(`#${currentTabId} .results-content`); + if (tabOutputElm) { + tabOutputElm.innerHTML = `
Query failed: ${e.message}
`; + } + setTimeout(() => { errorElm.style.opacity = 0; setTimeout(() => { @@ -102,7 +108,7 @@ function execute(commands, tabId = currentTabId) { const executionTime = toc("Executing SQL"); if (!results) { - error({message: event.data.error}); + error({message: event.data.error || "Unknown error occurred"}); return; } @@ -125,6 +131,11 @@ function execute(commands, tabId = currentTabId) { } worker.postMessage({ action: 'exec', sql: commands }); + + // Set up error handling for the worker + worker.onerror = function(e) { + error(e); + }; } // Create an HTML table @@ -172,7 +183,11 @@ function execEditorContents() { createNewTab(); } - execute(editor.getValue() + ';'); + try { + execute(editor.getValue() + ';'); + } catch (e) { + error(e); + } // Add visual feedback for button click execBtn.classList.add('active'); @@ -298,6 +313,7 @@ function showNotification(message) { // Initialize resizable panels function initResizer() { const editorPanel = document.querySelector('.editor-panel'); + const isMobileView = window.matchMedia('(max-width: 768px)').matches; panelResizerElm.addEventListener('mousedown', function(e) { isResizing = true; @@ -312,7 +328,7 @@ function initResizer() { let newWidth; // Check if we're in mobile view (flexbox column) - const isMobileView = window.getComputedStyle(document.querySelector('.app-container')).flexDirection === 'column'; + const isMobileView = window.matchMedia('(max-width: 768px)').matches; if (isMobileView) { // In mobile view, resize height instead of width @@ -341,6 +357,15 @@ function initResizer() { panelResizerElm.classList.remove('active'); } }); + + // Set initial width/height based on view + if (isMobileView) { + editorPanel.style.height = '50%'; + editorPanel.style.width = ''; + } else { + editorPanel.style.width = '50%'; + editorPanel.style.height = ''; + } } // Initialize tabs @@ -368,6 +393,12 @@ function initTabs() { } } }); + + // Initialize the first tab + const firstTab = document.querySelector('.tab[data-tab="tab1"]'); + if (firstTab) { + setActiveTab('tab1'); + } } // Create a new results tab @@ -535,116 +566,23 @@ window.addEventListener('resize', function() { } }); -// Add CSS for new elements -const style = document.createElement('style'); -style.textContent = ` -.loading { - display: flex; - align-items: center; - justify-content: center; - flex-direction: column; - height: 100px; - color: rgba(255, 255, 255, 0.7); -} - -.spinner { - width: 30px; - height: 30px; - border: 3px solid rgba(79, 190, 255, 0.3); - border-radius: 50%; - border-top-color: #4fbeff; - animation: spin 1s ease-in-out infinite; - margin-bottom: 15px; -} - -@keyframes spin { - to { transform: rotate(360deg); } -} - -.table-wrapper { - margin-bottom: 20px; -} - -.table-caption { - color: rgba(255, 255, 255, 0.6); - font-size: 0.85em; - margin-bottom: 8px; - text-align: right; -} - -.no-results { - color: rgba(255, 255, 255, 0.5); - text-align: center; - padding: 30px; -} - -.notification { - position: fixed; - bottom: -60px; - left: 50%; - transform: translateX(-50%); - background: rgba(40, 60, 80, 0.9); - color: #fff; - padding: 12px 20px; - border-radius: 8px; - box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3); - transition: bottom 0.3s ease; - z-index: 1000; - border-left: 3px solid #4fbeff; -} - -.notification.show { - bottom: 20px; -} - -.button.active { - transform: translateY(1px); - box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3) inset; -} - -.results-header, .editor-header { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 8px; - color: rgba(255, 255, 255, 0.7); - font-weight: 500; -} - -.actions { - display: flex; - flex-wrap: wrap; - margin: 15px 0; -} - -.github-corner:hover .octo-arm { - animation: octocat-wave 560ms ease-in-out; -} - -@keyframes octocat-wave { - 0%, 100% { transform: rotate(0); } - 20%, 60% { transform: rotate(-25deg); } - 40%, 80% { transform: rotate(10deg); } -} - -@media (max-width: 500px) { - .github-corner:hover .octo-arm { - animation: none; - } - .github-corner .octo-arm { - animation: octocat-wave 560ms ease-in-out; - } -} -`; -document.head.appendChild(style); - // Add keyboard shortcuts info document.addEventListener('DOMContentLoaded', function() { const editorHeader = document.querySelector('.editor-header'); if (editorHeader) { const shortcuts = document.createElement('div'); shortcuts.className = 'shortcuts'; - shortcuts.innerHTML = 'Keyboard shortcuts'; + shortcuts.innerHTML = ` + + Ctrl+Enter + + + Ctrl+S + + + Ctrl+Space + + `; editorHeader.appendChild(shortcuts); } }); diff --git a/examples/GUI/index.html b/examples/GUI/index.html index 19f53249..1036247f 100644 --- a/examples/GUI/index.html +++ b/examples/GUI/index.html @@ -54,13 +54,8 @@

SQL.js Interpreter

-
+
SQL Editor -
- - Ctrl+Enter - -
@@ -107,7 +102,7 @@

SQL.js Interpreter

-
Results will be displayed here
+
Results will be displayed here
From f10e0349d3b36b57e54f73dbd88276cce7364cf3 Mon Sep 17 00:00:00 2001 From: lovasoa Date: Sat, 15 Mar 2025 22:39:18 +0000 Subject: [PATCH 09/21] templates --- examples/GUI/gui.js | 247 ++++++++++++++++++++++++++++------------ examples/GUI/index.html | 67 +++++++++++ 2 files changed, 241 insertions(+), 73 deletions(-) diff --git a/examples/GUI/gui.js b/examples/GUI/gui.js index c761cee3..685c033d 100644 --- a/examples/GUI/gui.js +++ b/examples/GUI/gui.js @@ -46,7 +46,20 @@ function error(e) { // Clear loading spinner in the current tab when an error occurs const tabOutputElm = document.querySelector(`#${currentTabId} .results-content`); if (tabOutputElm) { - tabOutputElm.innerHTML = `
Query failed: ${e.message}
`; + tabOutputElm.innerHTML = ''; + + // Use error template + const errorTemplate = document.getElementById('error-template'); + const errorClone = errorTemplate.content.cloneNode(true); + const errorDiv = errorClone.querySelector('.error-result'); + + // Set error message + const errorMessage = document.createElement('span'); + errorMessage.slot = 'error-message'; + errorMessage.textContent = `Query failed: ${e.message}`; + errorDiv.appendChild(errorMessage); + + tabOutputElm.appendChild(errorDiv); } setTimeout(() => { @@ -64,19 +77,38 @@ function noerror() { // Status updates function updateStatus(type, message) { + const createStatusSpan = (className, text) => { + const span = document.createElement('span'); + span.className = className; + span.textContent = text; + return span; + }; + switch(type) { case 'executing': - editorStatusElm.innerHTML = `Executing query...`; - resultsStatusElm.innerHTML = `Executing query...`; + editorStatusElm.innerHTML = ''; + editorStatusElm.appendChild(createStatusSpan('status-info', 'Executing query...')); + + resultsStatusElm.innerHTML = ''; + resultsStatusElm.appendChild(createStatusSpan('status-info', 'Executing query...')); break; + case 'success': - editorStatusElm.innerHTML = `Query executed successfully`; - resultsStatusElm.innerHTML = `${message}`; + editorStatusElm.innerHTML = ''; + editorStatusElm.appendChild(createStatusSpan('status-success', 'Query executed successfully')); + + resultsStatusElm.innerHTML = ''; + resultsStatusElm.appendChild(createStatusSpan('status-success', message)); break; + case 'error': - editorStatusElm.innerHTML = `Query failed`; - resultsStatusElm.innerHTML = `${message}`; + editorStatusElm.innerHTML = ''; + editorStatusElm.appendChild(createStatusSpan('status-error', 'Query failed')); + + resultsStatusElm.innerHTML = ''; + resultsStatusElm.appendChild(createStatusSpan('status-error', message)); break; + default: editorStatusElm.textContent = message; break; @@ -93,12 +125,27 @@ function execute(commands, tabId = currentTabId) { tic(); updateStatus('executing'); + // Check if we need to create a new tab + // If the current tab is the initial tab and it hasn't been used yet, use it + // Otherwise, create a new tab + const currentTabPanel = document.getElementById(currentTabId); + const isInitialUnusedTab = currentTabId === 'tab1' && + currentTabPanel && + currentTabPanel.querySelector('.results-content').innerHTML.includes('Results will be displayed here'); + + if (!isInitialUnusedTab) { + tabId = createNewTab(); + } + // Get the output element for the current tab const tabOutputElm = document.querySelector(`#${tabId} .results-content`); if (!tabOutputElm) return; - // Show loading indicator - tabOutputElm.innerHTML = '
Executing query...
'; + // Show loading indicator using template + tabOutputElm.innerHTML = ''; + const loadingTemplate = document.getElementById('loading-template'); + const loadingClone = loadingTemplate.content.cloneNode(true); + tabOutputElm.appendChild(loadingClone); // Add to query history addToHistory(commands); @@ -116,7 +163,10 @@ function execute(commands, tabId = currentTabId) { tabOutputElm.innerHTML = ""; if (results.length === 0) { - tabOutputElm.innerHTML = '
Query executed successfully. No results to display.
'; + const noResultsDiv = document.createElement('div'); + noResultsDiv.className = 'no-results'; + noResultsDiv.textContent = 'Query executed successfully. No results to display.'; + tabOutputElm.appendChild(noResultsDiv); updateStatus('success', 'Query executed with no results'); return; } @@ -140,36 +190,50 @@ function execute(commands, tabId = currentTabId) { // Create an HTML table var tableCreate = function () { - function valconcat(vals, tagName) { - if (vals.length === 0) return ''; - var open = '<' + tagName + '>', close = ''; - return open + vals.join(close + open) + close; - } return function (columns, values) { - var tbl = document.createElement('table'); - var html = '' + valconcat(columns, 'th') + ''; + // Use the table template + const tableTemplate = document.getElementById('table-template'); + const tableClone = tableTemplate.content.cloneNode(true); + const wrapper = tableClone.querySelector('.table-wrapper'); + const table = tableClone.querySelector('table'); + + // Set row and column counts + wrapper.querySelector('.row-count').textContent = `${values.length} row${values.length !== 1 ? 's' : ''}`; + wrapper.querySelector('.column-count').textContent = `${columns.length} column${columns.length !== 1 ? 's' : ''}`; + + // Create header cells + const thead = table.querySelector('thead tr'); + thead.innerHTML = ''; // Clear the slot + columns.forEach(column => { + const th = document.createElement('th'); + th.textContent = column; + thead.appendChild(th); + }); + + // Create data rows + const tbody = table.querySelector('tbody'); + tbody.innerHTML = ''; // Clear the slot if (values.length === 0) { - html += 'No results'; + const emptyRow = document.createElement('tr'); + const emptyCell = document.createElement('td'); + emptyCell.className = 'no-results'; + emptyCell.textContent = 'No results'; + emptyCell.colSpan = columns.length; + emptyRow.appendChild(emptyCell); + tbody.appendChild(emptyRow); } else { - var rows = values.map(function (v) { return valconcat(v, 'td'); }); - html += '' + valconcat(rows, 'tr') + ''; + values.forEach(rowData => { + const row = document.createElement('tr'); + rowData.forEach(cellData => { + const cell = document.createElement('td'); + cell.textContent = cellData; + row.appendChild(cell); + }); + tbody.appendChild(row); + }); } - tbl.innerHTML = html; - - // Add a wrapper with a caption showing the number of rows - var wrapper = document.createElement('div'); - wrapper.className = 'table-wrapper'; - var caption = document.createElement('div'); - caption.className = 'table-caption'; - caption.innerHTML = ` - ${values.length} row${values.length !== 1 ? 's' : ''} - ${columns.length} column${columns.length !== 1 ? 's' : ''} - `; - wrapper.appendChild(caption); - wrapper.appendChild(tbl); - return wrapper; } }(); @@ -178,11 +242,7 @@ var tableCreate = function () { function execEditorContents() { noerror(); - // Create a new tab if needed - if (document.querySelectorAll('.results-tabs .tab').length <= 2) { // Only the first tab and + button - createNewTab(); - } - + // Use the current tab if it exists, otherwise create a new one try { execute(editor.getValue() + ';'); } catch (e) { @@ -237,8 +297,7 @@ dbFileElm.onchange = function () { // Show the schema of the loaded database editor.setValue("SELECT `name`, `sql`\n FROM `sqlite_master`\n WHERE type='table';"); - // Create a new tab for the results - createNewTab(); + // Execute the query (this will create a new tab if needed) execEditorContents(); // Show success notification @@ -300,8 +359,11 @@ function showNotification(message) { document.body.appendChild(notification); } - // Set message and show + // Clear existing content and set new message + notification.textContent = ''; notification.textContent = message; + + // Show notification notification.classList.add('show'); // Hide after 3 seconds @@ -397,6 +459,18 @@ function initTabs() { // Initialize the first tab const firstTab = document.querySelector('.tab[data-tab="tab1"]'); if (firstTab) { + // Clear the first tab's content + firstTab.innerHTML = ''; + + // Add the tab text directly + firstTab.textContent = `Result ${tabCounter}`; + + // Add close button + const closeBtn = document.createElement('span'); + closeBtn.className = 'tab-close'; + closeBtn.textContent = '×'; + firstTab.appendChild(closeBtn); + setActiveTab('tab1'); } } @@ -406,26 +480,33 @@ function createNewTab() { tabCounter++; const tabId = `tab${tabCounter}`; - // Create tab button - const tab = document.createElement('button'); - tab.className = 'tab'; + // Create tab button using template + const tabTemplate = document.getElementById('tab-template'); + const tabClone = tabTemplate.content.cloneNode(true); + const tab = tabClone.querySelector('.tab'); tab.dataset.tab = tabId; - tab.innerHTML = `Result ${tabCounter} ×`; + + // Clear any existing content in the tab + tab.innerHTML = ''; + + // Add the tab text directly (no slots) + tab.textContent = `Result ${tabCounter}`; + + // Add close button + const closeBtn = document.createElement('span'); + closeBtn.className = 'tab-close'; + closeBtn.textContent = '×'; + tab.appendChild(closeBtn); // Insert before the + button resultsTabs.insertBefore(tab, newTabBtn); - // Create tab panel - const tabPanel = document.createElement('div'); - tabPanel.className = 'tab-panel'; + // Create tab panel using template + const panelTemplate = document.getElementById('tab-panel-template'); + const panelClone = panelTemplate.content.cloneNode(true); + const tabPanel = panelClone.querySelector('.tab-panel'); tabPanel.id = tabId; - // Create results content container - const resultsContent = document.createElement('div'); - resultsContent.className = 'results-content'; - resultsContent.textContent = 'Execute a query to see results'; - - tabPanel.appendChild(resultsContent); document.querySelector('.results-panel .panel-content').appendChild(tabPanel); // Set as active @@ -506,9 +587,11 @@ function addToHistory(query) { function updateHistoryUI() { queryHistoryElm.innerHTML = ''; - queryHistory.forEach((item, index) => { - const historyItem = document.createElement('div'); - historyItem.className = 'history-item'; + queryHistory.forEach((item) => { + // Use history item template + const historyTemplate = document.getElementById('history-item-template'); + const historyClone = historyTemplate.content.cloneNode(true); + const historyItem = historyClone.querySelector('.history-item'); // Format timestamp const timestamp = item.timestamp; @@ -519,10 +602,18 @@ function updateHistoryUI() { item.query.substring(0, 60) + '...' : item.query; - historyItem.innerHTML = ` -
${queryPreview}
-
${timeString}
- `; + // Set query preview + const queryPreviewEl = document.createElement('span'); + queryPreviewEl.slot = 'query-preview'; + queryPreviewEl.textContent = queryPreview; + historyItem.querySelector('.history-query').appendChild(queryPreviewEl); + historyItem.querySelector('.history-query').title = item.query; + + // Set query time + const queryTimeEl = document.createElement('span'); + queryTimeEl.slot = 'query-time'; + queryTimeEl.textContent = timeString; + historyItem.querySelector('.history-time').appendChild(queryTimeEl); // Add click handler to load query historyItem.addEventListener('click', () => { @@ -572,17 +663,27 @@ document.addEventListener('DOMContentLoaded', function() { if (editorHeader) { const shortcuts = document.createElement('div'); shortcuts.className = 'shortcuts'; - shortcuts.innerHTML = ` - - Ctrl+Enter - - - Ctrl+S - - - Ctrl+Space - - `; + + // Create shortcut elements using template + const addShortcut = (title, keyText) => { + const shortcutTemplate = document.getElementById('shortcut-template'); + const shortcutClone = shortcutTemplate.content.cloneNode(true); + const shortcut = shortcutClone.querySelector('span'); + shortcut.title = title; + + const keySlot = document.createElement('span'); + keySlot.slot = 'key'; + keySlot.textContent = keyText; + shortcut.appendChild(keySlot); + + shortcuts.appendChild(shortcut); + }; + + // Add all shortcuts + addShortcut('Execute: Ctrl/Cmd+Enter', 'Ctrl+Enter'); + addShortcut('Save DB: Ctrl/Cmd+S', 'Ctrl+S'); + addShortcut('Toggle History: Ctrl+Space', 'Ctrl+Space'); + editorHeader.appendChild(shortcuts); } }); diff --git a/examples/GUI/index.html b/examples/GUI/index.html index 1036247f..350b6dbb 100644 --- a/examples/GUI/index.html +++ b/examples/GUI/index.html @@ -123,6 +123,73 @@

SQL.js Interpreter

+ + + + + + + + + + + + + + +

SQL.js Interpreter

SQL Editor +
+ +
- +
+
+ +
From c0124d7153e8b7a8bcf1d1ced29ac5272e98995b Mon Sep 17 00:00:00 2001 From: lovasoa Date: Sat, 15 Mar 2025 23:10:34 +0000 Subject: [PATCH 13/21] snippets in history --- examples/GUI/demo.css | 11 +++- examples/GUI/gui.js | 110 ++++++++++------------------------------ examples/GUI/index.html | 14 +---- 3 files changed, 38 insertions(+), 97 deletions(-) diff --git a/examples/GUI/demo.css b/examples/GUI/demo.css index 05f1774d..8733e00c 100644 --- a/examples/GUI/demo.css +++ b/examples/GUI/demo.css @@ -471,7 +471,7 @@ footer a:hover { } .query-history.show { - max-height: 300px; + max-height: 400px; height: auto; opacity: 1; visibility: visible; @@ -500,6 +500,15 @@ footer a:hover { background: rgba(255, 255, 255, 0.05); } +.history-item.snippet { + background: rgba(43, 106, 74, 0.1); + border-left: 3px solid var(--accent-green); +} + +.history-item.snippet:hover { + background: rgba(43, 106, 74, 0.2); +} + .history-query { font-family: 'JetBrains Mono', monospace; font-size: 0.85em; diff --git a/examples/GUI/gui.js b/examples/GUI/gui.js index 10d17fb5..b015d193 100644 --- a/examples/GUI/gui.js +++ b/examples/GUI/gui.js @@ -13,9 +13,7 @@ const elements = { queryHistoryElm: document.getElementById('queryHistory'), toggleHistoryBtn: document.getElementById('toggleHistory'), resultsTabs: document.getElementById('resultsTabs'), - newTabBtn: document.getElementById('newTabBtn'), - snippetsToggleBtn: document.getElementById('toggleSnippets'), - snippetsMenuElm: document.getElementById('snippetsMenu') + newTabBtn: document.getElementById('newTabBtn') }; // State @@ -41,25 +39,13 @@ const sqlSnippets = { name: 'Blog App Schema', sql: "-- Complete Blog Application Schema\n\n-- Users table\nDROP TABLE IF EXISTS users;\nCREATE TABLE users (\n id INTEGER PRIMARY KEY,\n username TEXT NOT NULL UNIQUE,\n email TEXT UNIQUE,\n password_hash TEXT NOT NULL,\n created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n);\n\n-- Insert sample users\nINSERT INTO users (username, email, password_hash, created_at) VALUES\n ('alice', 'alice@example.com', 'hash1', '2022-01-10'),\n ('bob', 'bob@example.com', 'hash2', '2022-01-15'),\n ('carol', 'carol@example.com', 'hash3', '2022-02-20');\n\n-- Posts table\nDROP TABLE IF EXISTS posts;\nCREATE TABLE posts (\n id INTEGER PRIMARY KEY,\n user_id INTEGER NOT NULL,\n title TEXT NOT NULL,\n content TEXT NOT NULL,\n published BOOLEAN DEFAULT 0,\n created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE\n);\n\n-- Insert sample posts\nINSERT INTO posts (user_id, title, content, published, created_at) VALUES\n (1, 'First Post', 'This is my first post content', 1, '2022-01-12'),\n (1, 'Second Post', 'This is another post by Alice', 1, '2022-01-18'),\n (2, 'Hello World', 'Bob\\'s first post content', 1, '2022-01-20'),\n (3, 'Introduction', 'Hello from Carol', 1, '2022-02-25'),\n (2, 'Draft Post', 'This is a draft', 0, '2022-02-28');\n\n-- Comments table\nDROP TABLE IF EXISTS comments;\nCREATE TABLE comments (\n id INTEGER PRIMARY KEY,\n post_id INTEGER NOT NULL,\n user_id INTEGER NOT NULL,\n content TEXT NOT NULL,\n created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n FOREIGN KEY (post_id) REFERENCES posts(id) ON DELETE CASCADE,\n FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE\n);\n\n-- Insert sample comments\nINSERT INTO comments (post_id, user_id, content, created_at) VALUES\n (1, 2, 'Great post!', '2022-01-13'),\n (1, 3, 'I agree with Bob', '2022-01-14'),\n (3, 1, 'Welcome Bob!', '2022-01-21'),\n (4, 2, 'Nice to meet you Carol', '2022-02-26');\n\n-- Query: Show posts with comment counts\nSELECT \n p.id, \n p.title, \n u.username as author,\n COUNT(c.id) as comment_count\nFROM posts p\nJOIN users u ON p.user_id = u.id\nLEFT JOIN comments c ON c.post_id = p.id\nWHERE p.published = 1\nGROUP BY p.id\nORDER BY p.created_at DESC;" }, - 'e-commerce': { - name: 'E-commerce Schema', - sql: "-- E-commerce Database Schema\n\n-- Products table\nDROP TABLE IF EXISTS products;\nCREATE TABLE products (\n id INTEGER PRIMARY KEY,\n name TEXT NOT NULL,\n description TEXT,\n price DECIMAL(10,2) NOT NULL,\n stock_quantity INTEGER NOT NULL DEFAULT 0,\n category TEXT\n);\n\n-- Insert sample products\nINSERT INTO products (name, description, price, stock_quantity, category) VALUES\n ('Smartphone', 'Latest model smartphone', 699.99, 50, 'Electronics'),\n ('Laptop', 'High performance laptop', 1299.99, 25, 'Electronics'),\n ('Headphones', 'Noise cancelling headphones', 199.99, 100, 'Electronics'),\n ('T-shirt', 'Cotton t-shirt', 19.99, 200, 'Clothing'),\n ('Jeans', 'Blue denim jeans', 49.99, 150, 'Clothing');\n\n-- Customers table\nDROP TABLE IF EXISTS customers;\nCREATE TABLE customers (\n id INTEGER PRIMARY KEY,\n name TEXT NOT NULL,\n email TEXT UNIQUE,\n address TEXT,\n created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n);\n\n-- Insert sample customers\nINSERT INTO customers (name, email, address) VALUES\n ('John Doe', 'john@example.com', '123 Main St'),\n ('Jane Smith', 'jane@example.com', '456 Oak Ave'),\n ('Mike Johnson', 'mike@example.com', '789 Pine Rd');\n\n-- Orders table\nDROP TABLE IF EXISTS orders;\nCREATE TABLE orders (\n id INTEGER PRIMARY KEY,\n customer_id INTEGER NOT NULL,\n order_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n status TEXT DEFAULT 'pending',\n total DECIMAL(10,2) NOT NULL,\n FOREIGN KEY (customer_id) REFERENCES customers(id)\n);\n\n-- Insert sample orders\nINSERT INTO orders (customer_id, order_date, status, total) VALUES\n (1, '2023-01-15', 'completed', 919.98),\n (2, '2023-01-20', 'completed', 1299.99),\n (3, '2023-02-01', 'processing', 249.98),\n (1, '2023-02-15', 'pending', 199.99);\n\n-- Order items table\nDROP TABLE IF EXISTS order_items;\nCREATE TABLE order_items (\n id INTEGER PRIMARY KEY,\n order_id INTEGER NOT NULL,\n product_id INTEGER NOT NULL,\n quantity INTEGER NOT NULL,\n price DECIMAL(10,2) NOT NULL,\n FOREIGN KEY (order_id) REFERENCES orders(id),\n FOREIGN KEY (product_id) REFERENCES products(id)\n);\n\n-- Insert sample order items\nINSERT INTO order_items (order_id, product_id, quantity, price) VALUES\n (1, 1, 1, 699.99),\n (1, 3, 1, 199.99),\n (2, 2, 1, 1299.99),\n (3, 4, 5, 19.99),\n (3, 5, 3, 49.99),\n (4, 3, 1, 199.99);\n\n-- Query: Show customer orders with items\nSELECT \n c.name as customer,\n o.id as order_id,\n o.order_date,\n o.status,\n p.name as product,\n oi.quantity,\n oi.price,\n (oi.quantity * oi.price) as subtotal\nFROM customers c\nJOIN orders o ON c.id = o.customer_id\nJOIN order_items oi ON o.id = oi.order_id\nJOIN products p ON oi.product_id = p.id\nORDER BY o.order_date DESC, c.name;" - }, 'recursive-query': { name: 'Recursive Query', sql: "-- Employee Hierarchy with Recursive CTE\n\n-- Create employees table with manager relationship\nDROP TABLE IF EXISTS employees;\nCREATE TABLE employees (\n id INTEGER PRIMARY KEY,\n name TEXT NOT NULL,\n title TEXT NOT NULL,\n manager_id INTEGER,\n salary NUMERIC,\n FOREIGN KEY (manager_id) REFERENCES employees(id)\n);\n\n-- Insert sample hierarchical data\nINSERT INTO employees (id, name, title, manager_id, salary) VALUES\n (1, 'Mark Johnson', 'CEO', NULL, 250000),\n (2, 'Sarah Williams', 'CTO', 1, 180000),\n (3, 'Michael Brown', 'CFO', 1, 175000),\n (4, 'Patricia Davis', 'Engineering Director', 2, 150000),\n (5, 'Robert Wilson', 'Finance Director', 3, 145000),\n (6, 'Linda Miller', 'Senior Developer', 4, 120000),\n (7, 'James Taylor', 'Senior Developer', 4, 120000),\n (8, 'Elizabeth Anderson', 'Accountant', 5, 95000),\n (9, 'David Thomas', 'Junior Developer', 6, 85000),\n (10, 'Jennifer Jackson', 'Junior Developer', 7, 85000);\n\n-- Recursive query to show employee hierarchy\nWITH RECURSIVE employee_hierarchy AS (\n -- Base case: top-level employees (no manager)\n SELECT \n id, \n name, \n title, \n manager_id, \n salary,\n 0 AS level,\n name AS path\n FROM employees\n WHERE manager_id IS NULL\n \n UNION ALL\n \n -- Recursive case: employees with managers\n SELECT \n e.id, \n e.name, \n e.title, \n e.manager_id, \n e.salary,\n eh.level + 1 AS level,\n eh.path || ' > ' || e.name AS path\n FROM employees e\n JOIN employee_hierarchy eh ON e.manager_id = eh.id\n)\n\n-- Query the hierarchy\nSELECT \n id,\n printf('%.' || (level * 4) || 's%s', '', name) AS employee,\n title,\n level,\n salary,\n path\nFROM employee_hierarchy\nORDER BY path;" }, - 'complex-subquery': { - name: 'Complex Subqueries', - sql: "-- Complex Subqueries Example\n\n-- Create sample tables\nDROP TABLE IF EXISTS departments;\nCREATE TABLE departments (\n id INTEGER PRIMARY KEY,\n name TEXT NOT NULL\n);\n\nDROP TABLE IF EXISTS employees;\nCREATE TABLE employees (\n id INTEGER PRIMARY KEY,\n name TEXT NOT NULL,\n department_id INTEGER,\n salary NUMERIC,\n hire_date DATE,\n FOREIGN KEY (department_id) REFERENCES departments(id)\n);\n\nDROP TABLE IF EXISTS projects;\nCREATE TABLE projects (\n id INTEGER PRIMARY KEY,\n name TEXT NOT NULL,\n budget NUMERIC\n);\n\nDROP TABLE IF EXISTS employee_projects;\nCREATE TABLE employee_projects (\n employee_id INTEGER,\n project_id INTEGER,\n hours_worked NUMERIC,\n PRIMARY KEY (employee_id, project_id),\n FOREIGN KEY (employee_id) REFERENCES employees(id),\n FOREIGN KEY (project_id) REFERENCES projects(id)\n);\n\n-- Insert sample data\nINSERT INTO departments (id, name) VALUES\n (1, 'Engineering'),\n (2, 'Marketing'),\n (3, 'Finance'),\n (4, 'HR');\n\nINSERT INTO employees (id, name, department_id, salary, hire_date) VALUES\n (1, 'Alice Smith', 1, 85000, '2020-01-15'),\n (2, 'Bob Johnson', 2, 72000, '2019-03-20'),\n (3, 'Carol Williams', 1, 92000, '2018-11-07'),\n (4, 'Dave Brown', 3, 115000, '2017-05-12'),\n (5, 'Eve Davis', 1, 110000, '2021-08-30'),\n (6, 'Frank Miller', 2, 68000, '2020-04-18'),\n (7, 'Grace Wilson', 3, 95000, '2019-12-01'),\n (8, 'Henry Garcia', 4, 75000, '2021-02-15');\n\nINSERT INTO projects (id, name, budget) VALUES\n (1, 'Website Redesign', 150000),\n (2, 'Mobile App', 200000),\n (3, 'Database Migration', 100000),\n (4, 'Marketing Campaign', 80000);\n\nINSERT INTO employee_projects (employee_id, project_id, hours_worked) VALUES\n (1, 1, 120), (1, 2, 80),\n (2, 4, 150),\n (3, 1, 100), (3, 2, 120), (3, 3, 40),\n (4, 3, 60),\n (5, 2, 180), (5, 3, 30),\n (6, 4, 140),\n (7, 3, 80);\n\n-- Complex query 1: Find employees who work on projects with a budget greater than average\nSELECT DISTINCT e.name, e.salary\nFROM employees e\nJOIN employee_projects ep ON e.id = ep.employee_id\nWHERE ep.project_id IN (\n SELECT id FROM projects WHERE budget > (\n SELECT AVG(budget) FROM projects\n )\n)\nORDER BY e.salary DESC;\n\n-- Complex query 2: Find departments with employees who have above-average salaries\nSELECT \n d.name AS department,\n COUNT(*) AS employee_count,\n ROUND(AVG(e.salary), 2) AS avg_salary\nFROM departments d\nJOIN employees e ON d.id = e.department_id\nWHERE e.salary > (\n SELECT AVG(salary) FROM employees\n)\nGROUP BY d.id\nORDER BY avg_salary DESC;\n\n-- Complex query 3: Find employees who work on the most projects\nSELECT \n e.name,\n COUNT(ep.project_id) AS project_count,\n SUM(ep.hours_worked) AS total_hours\nFROM employees e\nJOIN employee_projects ep ON e.id = ep.employee_id\nGROUP BY e.id\nHAVING COUNT(ep.project_id) = (\n SELECT MAX(project_count)\n FROM (\n SELECT COUNT(project_id) AS project_count\n FROM employee_projects\n GROUP BY employee_id\n )\n)\nORDER BY total_hours DESC;" - }, 'window-functions': { name: 'Window Functions', - sql: "-- Window Functions Example\n\n-- Create sales table\nDROP TABLE IF EXISTS sales;\nCREATE TABLE sales (\n id INTEGER PRIMARY KEY,\n salesperson TEXT NOT NULL,\n region TEXT NOT NULL,\n amount NUMERIC NOT NULL,\n sale_date DATE NOT NULL\n);\n\n-- Insert sample data\nINSERT INTO sales (salesperson, region, amount, sale_date) VALUES\n ('Alice', 'North', 12500, '2023-01-05'),\n ('Bob', 'South', 8700, '2023-01-10'),\n ('Carol', 'East', 15200, '2023-01-12'),\n ('Dave', 'West', 7300, '2023-01-15'),\n ('Alice', 'North', 9800, '2023-02-03'),\n ('Bob', 'South', 11600, '2023-02-08'),\n ('Carol', 'East', 14100, '2023-02-15'),\n ('Dave', 'West', 9200, '2023-02-20'),\n ('Alice', 'North', 16700, '2023-03-05'),\n ('Bob', 'South', 10300, '2023-03-12'),\n ('Carol', 'East', 12800, '2023-03-18'),\n ('Dave', 'West', 8500, '2023-03-25');\n\n-- Window function queries\n\n-- 1. Running total of sales by salesperson\nSELECT\n salesperson,\n region,\n sale_date,\n amount,\n SUM(amount) OVER (\n PARTITION BY salesperson \n ORDER BY sale_date\n ) AS running_total\nFROM sales\nORDER BY salesperson, sale_date;\n\n-- 2. Rank salespeople by amount within each region\nSELECT\n region,\n salesperson,\n amount,\n RANK() OVER (\n PARTITION BY region \n ORDER BY amount DESC\n ) AS region_rank\nFROM sales\nORDER BY region, region_rank;\n\n-- 3. Calculate moving average of last 2 sales\nSELECT\n salesperson,\n sale_date,\n amount,\n AVG(amount) OVER (\n PARTITION BY salesperson \n ORDER BY sale_date \n ROWS BETWEEN 1 PRECEDING AND CURRENT ROW\n ) AS moving_avg_2\nFROM sales\nORDER BY salesperson, sale_date;\n\n-- 4. Compare each sale to the previous sale\nSELECT\n salesperson,\n sale_date,\n amount,\n LAG(amount, 1) OVER (\n PARTITION BY salesperson \n ORDER BY sale_date\n ) AS previous_amount,\n amount - LAG(amount, 1) OVER (\n PARTITION BY salesperson \n ORDER BY sale_date\n ) AS amount_change\nFROM sales\nORDER BY salesperson, sale_date;" - }, - 'json-functions': { - name: 'JSON Functions', - sql: "-- SQLite JSON Functions Example\n\n-- Create table with JSON data\nDROP TABLE IF EXISTS users;\nCREATE TABLE users (\n id INTEGER PRIMARY KEY,\n name TEXT NOT NULL,\n profile JSON\n);\n\n-- Insert sample data with JSON\nINSERT INTO users (name, profile) VALUES\n ('Alice', '{\"age\": 28, \"city\": \"New York\", \"skills\": [\"Python\", \"SQL\", \"JavaScript\"], \"contact\": {\"email\": \"alice@example.com\", \"phone\": \"555-1234\"}}'),\n ('Bob', '{\"age\": 35, \"city\": \"San Francisco\", \"skills\": [\"Java\", \"C++\", \"Ruby\"], \"contact\": {\"email\": \"bob@example.com\", \"phone\": \"555-5678\"}}'),\n ('Carol', '{\"age\": 42, \"city\": \"Chicago\", \"skills\": [\"SQL\", \"R\", \"Tableau\"], \"contact\": {\"email\": \"carol@example.com\"}}'),\n ('Dave', '{\"age\": 31, \"city\": \"Boston\", \"skills\": [\"Python\", \"SQL\"], \"contact\": {\"email\": \"dave@example.com\", \"phone\": \"555-9012\"}}');\n\n-- JSON queries\n\n-- 1. Extract simple values\nSELECT\n name,\n json_extract(profile, '$.age') AS age,\n json_extract(profile, '$.city') AS city\nFROM users\nORDER BY age;\n\n-- 2. Filter based on JSON values\nSELECT name, profile\nFROM users\nWHERE json_extract(profile, '$.age') > 30\nORDER BY json_extract(profile, '$.age');\n\n-- 3. Check for array elements\nSELECT name\nFROM users\nWHERE json_extract(profile, '$.skills') LIKE '%SQL%'\nORDER BY name;\n\n-- 4. Extract nested values\nSELECT\n name,\n json_extract(profile, '$.contact.email') AS email,\n json_extract(profile, '$.contact.phone') AS phone\nFROM users\nORDER BY name;\n\n-- 5. Count array elements\nSELECT\n name,\n json_array_length(json_extract(profile, '$.skills')) AS skill_count\nFROM users\nORDER BY skill_count DESC;" + sql: "-- Window Functions Example\n\n-- Create sales table\nDROP TABLE IF EXISTS sales;\nCREATE TABLE sales (\n id INTEGER PRIMARY KEY,\n salesperson TEXT NOT NULL,\n region TEXT NOT NULL,\n amount NUMERIC NOT NULL,\n sale_date DATE NOT NULL\n);\n\n-- Insert sample data\nINSERT INTO sales (salesperson, region, amount, sale_date) VALUES\n ('Alice', 'North', 12500, '2023-01-05'),\n ('Bob', 'South', 8700, '2023-01-10'),\n ('Carol', 'East', 15200, '2023-01-12'),\n ('Dave', 'West', 7300, '2023-01-15'),\n ('Alice', 'North', 9800, '2023-02-03'),\n ('Bob', 'South', 11600, '2023-02-08'),\n ('Carol', 'East', 14100, '2023-02-15'),\n ('Dave', 'West', 9200, '2023-02-20'),\n ('Alice', 'North', 16700, '2023-03-05'),\n ('Bob', 'South', 10300, '2023-03-12'),\n ('Carol', 'East', 12800, '2023-03-18'),\n ('Dave', 'West', 8500, '2023-03-25');\n\n-- Window function queries\n\n-- 1. Running total of sales by salesperson\nSELECT\n salesperson,\n region,\n sale_date,\n amount,\n SUM(amount) OVER (\n PARTITION BY salesperson \n ORDER BY sale_date\n ) AS running_total\nFROM sales\nORDER BY salesperson, sale_date;" } }; @@ -74,7 +60,7 @@ worker.postMessage({ action: 'open' }); initResizer(); initTabs(); initKeyboardShortcuts(); -initSnippetsMenu(); +initQueryHistory(); // Error handling function handleError(e) { @@ -644,7 +630,12 @@ function createHistoryItem(item) { const historyClone = historyTemplate.content.cloneNode(true); const historyItem = historyClone.querySelector('.history-item'); - const timeString = item.timestamp.toLocaleTimeString(); + // Add snippet class if it's a snippet + if (item.isSnippet) { + historyItem.classList.add('snippet'); + } + + const timeString = item.isSnippet ? `Example: ${item.snippetName}` : item.timestamp.toLocaleTimeString(); const queryPreview = truncateString(item.query, 60); const queryPreviewEl = document.createElement('span'); @@ -671,12 +662,6 @@ function truncateString(str, maxLength) { } function toggleQueryHistory() { - // Don't open history if there are no items - if (!elements.queryHistoryElm.classList.contains('show') && state.queryHistory.length === 0) { - showNotification('No query history yet'); - return; - } - const historyElement = elements.queryHistoryElm; const isVisible = historyElement.classList.contains('show'); @@ -696,6 +681,24 @@ function closeQueryHistory() { elements.queryHistoryElm.classList.remove('show'); } +// Initialize query history with snippets +function initQueryHistory() { + // Add snippets to history in reverse order so the most basic ones appear at the top + const snippetEntries = Object.entries(sqlSnippets); + for (let i = snippetEntries.length - 1; i >= 0; i--) { + const [id, snippet] = snippetEntries[i]; + state.queryHistory.push({ + query: snippet.sql, + timestamp: new Date(Date.now() - i * 60000), // Stagger timestamps + executionTime: 0, + isSnippet: true, + snippetName: snippet.name + }); + } + + updateHistoryUI(); +} + // Toggle history button elements.toggleHistoryBtn.addEventListener('click', toggleQueryHistory); @@ -767,62 +770,3 @@ function addShortcutInfo(container, title, keyText) { container.appendChild(shortcut); } - -// Initialize snippets menu -function initSnippetsMenu() { - if (!elements.snippetsToggleBtn || !elements.snippetsMenuElm) return; - - // Create snippet menu items - for (const [id, snippet] of Object.entries(sqlSnippets)) { - const item = document.createElement('div'); - item.className = 'snippet-item'; - item.textContent = snippet.name; - item.dataset.snippetId = id; - - item.addEventListener('click', () => { - editor.setValue(snippet.sql); - toggleSnippetsMenu(); - }); - - elements.snippetsMenuElm.appendChild(item); - } - - // Toggle button event - elements.snippetsToggleBtn.addEventListener('click', toggleSnippetsMenu); - - // Close menu when clicking outside - document.addEventListener('click', function(e) { - if (elements.snippetsMenuElm.classList.contains('show') && - !elements.snippetsMenuElm.contains(e.target) && - e.target !== elements.snippetsToggleBtn) { - closeSnippetsMenu(); - } - }); - - // Close menu when pressing Escape - document.addEventListener('keydown', function(e) { - if (e.key === 'Escape' && elements.snippetsMenuElm.classList.contains('show')) { - closeSnippetsMenu(); - } - }); -} - -function toggleSnippetsMenu() { - const menuElement = elements.snippetsMenuElm; - const isVisible = menuElement.classList.contains('show'); - - if (!isVisible) { - // Position the menu - const toggleBtnRect = elements.snippetsToggleBtn.getBoundingClientRect(); - menuElement.style.top = `${toggleBtnRect.bottom + 5}px`; - menuElement.style.right = `${window.innerWidth - toggleBtnRect.right}px`; - } - - menuElement.classList.toggle('show'); - elements.snippetsToggleBtn.classList.toggle('active'); -} - -function closeSnippetsMenu() { - elements.snippetsMenuElm.classList.remove('show'); - elements.snippetsToggleBtn.classList.remove('active'); -} diff --git a/examples/GUI/index.html b/examples/GUI/index.html index c46b7b37..7d2d089f 100644 --- a/examples/GUI/index.html +++ b/examples/GUI/index.html @@ -46,7 +46,7 @@

SQL.js Interpreter

- History + Examples & History
@@ -56,15 +56,6 @@

SQL.js Interpreter

SQL Editor -
- -