diff --git a/&1 b/&1 deleted file mode 100644 index e69de29bb..000000000 diff --git a/.github/workflows/napi.yml b/.github/workflows/napi.yml index 3ed3ec06e..c53237552 100644 --- a/.github/workflows/napi.yml +++ b/.github/workflows/napi.yml @@ -19,6 +19,10 @@ defaults: run: working-directory: bindings/javascript +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + jobs: build: timeout-minutes: 20 @@ -27,20 +31,18 @@ jobs: matrix: settings: - host: windows-latest - build: | - yarn build --target x86_64-pc-windows-msvc - yarn test target: x86_64-pc-windows-msvc + build: yarn workspace @tursodatabase/database napi-build --target x86_64-pc-windows-msvc - host: ubuntu-latest target: x86_64-unknown-linux-gnu docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-debian - build: yarn build --target x86_64-unknown-linux-gnu + build: yarn workspace @tursodatabase/database napi-build --target x86_64-unknown-linux-gnu - host: macos-latest target: aarch64-apple-darwin - build: yarn build --target aarch64-apple-darwin + build: yarn workspace @tursodatabase/database napi-build --target aarch64-apple-darwin - host: blacksmith-2vcpu-ubuntu-2404-arm target: aarch64-unknown-linux-gnu - build: yarn build --target aarch64-unknown-linux-gnu + build: yarn workspace @tursodatabase/database napi-build --target aarch64-unknown-linux-gnu - host: ubuntu-latest target: wasm32-wasip1-threads setup: | @@ -52,7 +54,7 @@ jobs: export CMAKE_BUILD_PARALLEL_LEVEL=$(nproc) export TARGET_CXXFLAGS="--target=wasm32-wasi-threads --sysroot=$(pwd)/wasi-sdk-25.0-x86_64-linux/share/wasi-sysroot -pthread -mllvm -wasm-enable-sjlj -lsetjmp" export TARGET_CFLAGS="$TARGET_CXXFLAGS" - yarn build --target wasm32-wasip1-threads + yarn workspace @tursodatabase/database-browser build name: stable - ${{ matrix.settings.target }} - node@20 runs-on: ${{ matrix.settings.host }} steps: @@ -88,6 +90,8 @@ jobs: shell: bash - name: Install dependencies run: yarn install + - name: Build common + run: yarn workspace @tursodatabase/database-common build - name: Setup node x86 uses: actions/setup-node@v4 if: matrix.settings.target == 'x86_64-pc-windows-msvc' @@ -110,8 +114,8 @@ jobs: with: name: bindings-${{ matrix.settings.target }} path: | - bindings/javascript/${{ env.APP_NAME }}.*.node - bindings/javascript/${{ env.APP_NAME }}.*.wasm + bindings/javascript/packages/native/${{ env.APP_NAME }}.*.node + bindings/javascript/packages/browser/${{ env.APP_NAME }}.*.wasm if-no-files-found: error test-linux-x64-gnu-binding: name: Test bindings on Linux-x64-gnu - node@${{ matrix.node }} @@ -131,20 +135,21 @@ jobs: node-version: ${{ matrix.node }} - name: Install dependencies run: yarn install - - name: Download artifacts + - name: Build common + run: yarn workspace @tursodatabase/database-common build + - name: Download all artifacts uses: actions/download-artifact@v4 with: - name: bindings-x86_64-unknown-linux-gnu - path: bindings/javascript + path: bindings/javascript/packages + merge-multiple: true - name: List packages run: ls -R . shell: bash - name: Test bindings - run: docker run --rm -v $(pwd):/build -w /build node:${{ matrix.node }}-slim yarn test + run: docker run --rm -v $(pwd):/build -w /build node:${{ matrix.node }}-slim yarn workspace @tursodatabase/database test publish: name: Publish runs-on: ubuntu-latest - if: startsWith(github.ref, 'refs/tags/v') permissions: contents: read id-token: write @@ -156,35 +161,35 @@ jobs: uses: useblacksmith/setup-node@v5 with: node-version: 20 - - name: Install dependencies - run: yarn install - - name: create npm dirs - run: yarn napi create-npm-dirs - name: Download all artifacts uses: actions/download-artifact@v4 with: - path: bindings/javascript/artifacts - - name: Move artifacts - run: yarn artifacts - - name: List packages - run: ls -R ./npm - shell: bash + path: bindings/javascript/packages + merge-multiple: true + - name: Install dependencies + run: yarn install + - name: Install dependencies + run: yarn tsc-build - name: Publish + if: "startsWith(github.ref, 'refs/tags/v')" run: | npm config set provenance true if git log -1 --pretty=%B | grep "^Turso [0-9]\+\.[0-9]\+\.[0-9]\+$"; then echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc - make publish-native - make publish-browser + npm publish --workspaces --access public elif git log -1 --pretty=%B | grep "^Turso [0-9]\+\.[0-9]\+\.[0-9]\+"; then echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc - make publish-native-next - make publish-browser-next + npm publish --workspaces --access public --tag next else - echo "Not a release, skipping publish" + echo "git log structure is unexpected, skip publishing" + npm publish --workspaces --dry-run fi env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + - name: Publish (dry-run) + if: "!startsWith(github.ref, 'refs/tags/v')" + run: | + npm publish --workspaces --dry-run \ No newline at end of file diff --git a/.gitignore b/.gitignore index 294912817..b851e8025 100644 --- a/.gitignore +++ b/.gitignore @@ -42,3 +42,5 @@ simulator.log **/*.txt profile.json.gz simulator-output/ + +&1 diff --git a/Cargo.lock b/Cargo.lock index 8ac5ac00f..3078152e6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -667,7 +667,7 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "core_tester" -version = "0.1.5-pre.3" +version = "0.1.5-pre.5" dependencies = [ "anyhow", "assert_cmd", @@ -2126,7 +2126,7 @@ dependencies = [ [[package]] name = "limbo_completion" -version = "0.1.5-pre.3" +version = "0.1.5-pre.5" dependencies = [ "mimalloc", "turso_ext", @@ -2134,7 +2134,7 @@ dependencies = [ [[package]] name = "limbo_crypto" -version = "0.1.5-pre.3" +version = "0.1.5-pre.5" dependencies = [ "blake3", "data-encoding", @@ -2147,7 +2147,7 @@ dependencies = [ [[package]] name = "limbo_csv" -version = "0.1.5-pre.3" +version = "0.1.5-pre.5" dependencies = [ "csv", "mimalloc", @@ -2157,7 +2157,7 @@ dependencies = [ [[package]] name = "limbo_ipaddr" -version = "0.1.5-pre.3" +version = "0.1.5-pre.5" dependencies = [ "ipnetwork", "mimalloc", @@ -2166,7 +2166,7 @@ dependencies = [ [[package]] name = "limbo_percentile" -version = "0.1.5-pre.3" +version = "0.1.5-pre.5" dependencies = [ "mimalloc", "turso_ext", @@ -2174,7 +2174,7 @@ dependencies = [ [[package]] name = "limbo_regexp" -version = "0.1.5-pre.3" +version = "0.1.5-pre.5" dependencies = [ "mimalloc", "regex", @@ -2183,7 +2183,7 @@ dependencies = [ [[package]] name = "limbo_sim" -version = "0.1.5-pre.3" +version = "0.1.5-pre.5" dependencies = [ "anyhow", "chrono", @@ -2216,7 +2216,7 @@ dependencies = [ [[package]] name = "limbo_sqlite_test_ext" -version = "0.1.5-pre.3" +version = "0.1.5-pre.5" dependencies = [ "cc", ] @@ -2971,7 +2971,7 @@ dependencies = [ [[package]] name = "py-turso" -version = "0.1.5-pre.3" +version = "0.1.5-pre.5" dependencies = [ "anyhow", "pyo3", @@ -3666,7 +3666,7 @@ checksum = "d372029cb5195f9ab4e4b9aef550787dce78b124fcaee8d82519925defcd6f0d" [[package]] name = "sql_generation" -version = "0.1.5-pre.3" +version = "0.1.5-pre.5" dependencies = [ "anarchist-readable-name-generator-lib 0.2.0", "anyhow", @@ -4176,7 +4176,7 @@ dependencies = [ [[package]] name = "turso" -version = "0.1.5-pre.3" +version = "0.1.5-pre.5" dependencies = [ "rand 0.8.5", "rand_chacha 0.3.1", @@ -4188,7 +4188,7 @@ dependencies = [ [[package]] name = "turso-java" -version = "0.1.5-pre.3" +version = "0.1.5-pre.5" dependencies = [ "jni", "thiserror 2.0.12", @@ -4197,7 +4197,7 @@ dependencies = [ [[package]] name = "turso_cli" -version = "0.1.5-pre.3" +version = "0.1.5-pre.5" dependencies = [ "anyhow", "cfg-if", @@ -4230,7 +4230,7 @@ dependencies = [ [[package]] name = "turso_core" -version = "0.1.5-pre.3" +version = "0.1.5-pre.5" dependencies = [ "aegis", "aes", @@ -4289,7 +4289,7 @@ dependencies = [ [[package]] name = "turso_dart" -version = "0.1.5-pre.3" +version = "0.1.5-pre.5" dependencies = [ "flutter_rust_bridge", "turso_core", @@ -4297,7 +4297,7 @@ dependencies = [ [[package]] name = "turso_ext" -version = "0.1.5-pre.3" +version = "0.1.5-pre.5" dependencies = [ "chrono", "getrandom 0.3.2", @@ -4306,7 +4306,7 @@ dependencies = [ [[package]] name = "turso_ext_tests" -version = "0.1.5-pre.3" +version = "0.1.5-pre.5" dependencies = [ "env_logger 0.11.7", "lazy_static", @@ -4317,7 +4317,7 @@ dependencies = [ [[package]] name = "turso_macros" -version = "0.1.5-pre.3" +version = "0.1.5-pre.5" dependencies = [ "proc-macro2", "quote", @@ -4326,18 +4326,19 @@ dependencies = [ [[package]] name = "turso_node" -version = "0.1.5-pre.3" +version = "0.1.5-pre.5" dependencies = [ "napi", "napi-build", "napi-derive", + "tracing", "tracing-subscriber", "turso_core", ] [[package]] name = "turso_parser" -version = "0.1.5-pre.3" +version = "0.1.5-pre.5" dependencies = [ "bitflags 2.9.0", "criterion", @@ -4353,7 +4354,7 @@ dependencies = [ [[package]] name = "turso_sqlite3" -version = "0.1.5-pre.3" +version = "0.1.5-pre.5" dependencies = [ "env_logger 0.11.7", "libc", @@ -4366,7 +4367,7 @@ dependencies = [ [[package]] name = "turso_sqlite3_parser" -version = "0.1.5-pre.3" +version = "0.1.5-pre.5" dependencies = [ "bitflags 2.9.0", "cc", @@ -4384,7 +4385,7 @@ dependencies = [ [[package]] name = "turso_stress" -version = "0.1.5-pre.3" +version = "0.1.5-pre.5" dependencies = [ "anarchist-readable-name-generator-lib 0.1.2", "antithesis_sdk", @@ -4400,7 +4401,7 @@ dependencies = [ [[package]] name = "turso_sync_engine" -version = "0.1.5-pre.3" +version = "0.1.5-pre.5" dependencies = [ "base64", "bytes", @@ -4426,7 +4427,7 @@ dependencies = [ [[package]] name = "turso_sync_js" -version = "0.1.5-pre.3" +version = "0.1.5-pre.5" dependencies = [ "genawaiter", "http", diff --git a/Cargo.toml b/Cargo.toml index 3bc527899..e393d48e3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,29 +33,29 @@ members = [ exclude = ["perf/latency/limbo"] [workspace.package] -version = "0.1.5-pre.3" +version = "0.1.5-pre.5" authors = ["the Limbo authors"] edition = "2021" license = "MIT" repository = "https://github.com/tursodatabase/turso" [workspace.dependencies] -turso = { path = "bindings/rust", version = "0.1.5-pre.3" } -turso_node = { path = "bindings/javascript", version = "0.1.5-pre.3" } -limbo_completion = { path = "extensions/completion", version = "0.1.5-pre.3" } -turso_core = { path = "core", version = "0.1.5-pre.3" } -turso_sync_engine = { path = "sync/engine", version = "0.1.5-pre.3" } -limbo_crypto = { path = "extensions/crypto", version = "0.1.5-pre.3" } -limbo_csv = { path = "extensions/csv", version = "0.1.5-pre.3" } -turso_ext = { path = "extensions/core", version = "0.1.5-pre.3" } -turso_ext_tests = { path = "extensions/tests", version = "0.1.5-pre.3" } -limbo_ipaddr = { path = "extensions/ipaddr", version = "0.1.5-pre.3" } -turso_macros = { path = "macros", version = "0.1.5-pre.3" } -limbo_percentile = { path = "extensions/percentile", version = "0.1.5-pre.3" } -limbo_regexp = { path = "extensions/regexp", version = "0.1.5-pre.3" } -turso_sqlite3_parser = { path = "vendored/sqlite3-parser", version = "0.1.5-pre.3" } -limbo_uuid = { path = "extensions/uuid", version = "0.1.5-pre.3" } -turso_parser = { path = "parser", version = "0.1.5-pre.3" } +turso = { path = "bindings/rust", version = "0.1.5-pre.5" } +turso_node = { path = "bindings/javascript", version = "0.1.5-pre.5" } +limbo_completion = { path = "extensions/completion", version = "0.1.5-pre.5" } +turso_core = { path = "core", version = "0.1.5-pre.5" } +turso_sync_engine = { path = "sync/engine", version = "0.1.5-pre.5" } +limbo_crypto = { path = "extensions/crypto", version = "0.1.5-pre.5" } +limbo_csv = { path = "extensions/csv", version = "0.1.5-pre.5" } +turso_ext = { path = "extensions/core", version = "0.1.5-pre.5" } +turso_ext_tests = { path = "extensions/tests", version = "0.1.5-pre.5" } +limbo_ipaddr = { path = "extensions/ipaddr", version = "0.1.5-pre.5" } +turso_macros = { path = "macros", version = "0.1.5-pre.5" } +limbo_percentile = { path = "extensions/percentile", version = "0.1.5-pre.5" } +limbo_regexp = { path = "extensions/regexp", version = "0.1.5-pre.5" } +turso_sqlite3_parser = { path = "vendored/sqlite3-parser", version = "0.1.5-pre.5" } +limbo_uuid = { path = "extensions/uuid", version = "0.1.5-pre.5" } +turso_parser = { path = "parser", version = "0.1.5-pre.5" } sql_generation = { path = "sql_generation" } strum = { version = "0.26", features = ["derive"] } strum_macros = "0.26" diff --git a/bindings/javascript/.gitignore b/bindings/javascript/.gitignore index 02f979110..43964d947 100644 --- a/bindings/javascript/.gitignore +++ b/bindings/javascript/.gitignore @@ -197,4 +197,4 @@ Cargo.lock *.node *.wasm -package.native.json +npm diff --git a/bindings/javascript/.npmignore b/bindings/javascript/.npmignore index ec144db2a..4c24ea24a 100644 --- a/bindings/javascript/.npmignore +++ b/bindings/javascript/.npmignore @@ -11,3 +11,5 @@ yarn.lock .yarn __test__ renovate.json +examples +perf diff --git a/bindings/javascript/Cargo.toml b/bindings/javascript/Cargo.toml index 077f07fb3..a3b2384fe 100644 --- a/bindings/javascript/Cargo.toml +++ b/bindings/javascript/Cargo.toml @@ -15,9 +15,11 @@ turso_core = { workspace = true } napi = { version = "3.1.3", default-features = false, features = ["napi6"] } napi-derive = { version = "3.1.1", default-features = true } tracing-subscriber = { version = "0.3.19", features = ["env-filter"] } +tracing.workspace = true [features] encryption = ["turso_core/encryption"] +browser = [] [build-dependencies] napi-build = "2.2.3" diff --git a/bindings/javascript/browser.js b/bindings/javascript/browser.js deleted file mode 100644 index 1959855f1..000000000 --- a/bindings/javascript/browser.js +++ /dev/null @@ -1 +0,0 @@ -export * from '@tursodatabase/database-wasm32-wasi' diff --git a/bindings/javascript/index.js b/bindings/javascript/index.js deleted file mode 100644 index 6bff52d98..000000000 --- a/bindings/javascript/index.js +++ /dev/null @@ -1,398 +0,0 @@ -// prettier-ignore -/* eslint-disable */ -// @ts-nocheck -/* auto-generated by NAPI-RS */ - -import { createRequire } from 'node:module' -const require = createRequire(import.meta.url) -const __dirname = new URL('.', import.meta.url).pathname - -const { readFileSync } = require('node:fs') -let nativeBinding = null -const loadErrors = [] - -const isMusl = () => { - let musl = false - if (process.platform === 'linux') { - musl = isMuslFromFilesystem() - if (musl === null) { - musl = isMuslFromReport() - } - if (musl === null) { - musl = isMuslFromChildProcess() - } - } - return musl -} - -const isFileMusl = (f) => f.includes('libc.musl-') || f.includes('ld-musl-') - -const isMuslFromFilesystem = () => { - try { - return readFileSync('/usr/bin/ldd', 'utf-8').includes('musl') - } catch { - return null - } -} - -const isMuslFromReport = () => { - let report = null - if (typeof process.report?.getReport === 'function') { - process.report.excludeNetwork = true - report = process.report.getReport() - } - if (!report) { - return null - } - if (report.header && report.header.glibcVersionRuntime) { - return false - } - if (Array.isArray(report.sharedObjects)) { - if (report.sharedObjects.some(isFileMusl)) { - return true - } - } - return false -} - -const isMuslFromChildProcess = () => { - try { - return require('child_process').execSync('ldd --version', { encoding: 'utf8' }).includes('musl') - } catch (e) { - // If we reach this case, we don't know if the system is musl or not, so is better to just fallback to false - return false - } -} - -function requireNative() { - if (process.env.NAPI_RS_NATIVE_LIBRARY_PATH) { - try { - nativeBinding = require(process.env.NAPI_RS_NATIVE_LIBRARY_PATH); - } catch (err) { - loadErrors.push(err) - } - } else if (process.platform === 'android') { - if (process.arch === 'arm64') { - try { - return require('./turso.android-arm64.node') - } catch (e) { - loadErrors.push(e) - } - try { - return require('@tursodatabase/database-android-arm64') - } catch (e) { - loadErrors.push(e) - } - } else if (process.arch === 'arm') { - try { - return require('./turso.android-arm-eabi.node') - } catch (e) { - loadErrors.push(e) - } - try { - return require('@tursodatabase/database-android-arm-eabi') - } catch (e) { - loadErrors.push(e) - } - } else { - loadErrors.push(new Error(`Unsupported architecture on Android ${process.arch}`)) - } - } else if (process.platform === 'win32') { - if (process.arch === 'x64') { - try { - return require('./turso.win32-x64-msvc.node') - } catch (e) { - loadErrors.push(e) - } - try { - return require('@tursodatabase/database-win32-x64-msvc') - } catch (e) { - loadErrors.push(e) - } - } else if (process.arch === 'ia32') { - try { - return require('./turso.win32-ia32-msvc.node') - } catch (e) { - loadErrors.push(e) - } - try { - return require('@tursodatabase/database-win32-ia32-msvc') - } catch (e) { - loadErrors.push(e) - } - } else if (process.arch === 'arm64') { - try { - return require('./turso.win32-arm64-msvc.node') - } catch (e) { - loadErrors.push(e) - } - try { - return require('@tursodatabase/database-win32-arm64-msvc') - } catch (e) { - loadErrors.push(e) - } - } else { - loadErrors.push(new Error(`Unsupported architecture on Windows: ${process.arch}`)) - } - } else if (process.platform === 'darwin') { - try { - return require('./turso.darwin-universal.node') - } catch (e) { - loadErrors.push(e) - } - try { - return require('@tursodatabase/database-darwin-universal') - } catch (e) { - loadErrors.push(e) - } - if (process.arch === 'x64') { - try { - return require('./turso.darwin-x64.node') - } catch (e) { - loadErrors.push(e) - } - try { - return require('@tursodatabase/database-darwin-x64') - } catch (e) { - loadErrors.push(e) - } - } else if (process.arch === 'arm64') { - try { - return require('./turso.darwin-arm64.node') - } catch (e) { - loadErrors.push(e) - } - try { - return require('@tursodatabase/database-darwin-arm64') - } catch (e) { - loadErrors.push(e) - } - } else { - loadErrors.push(new Error(`Unsupported architecture on macOS: ${process.arch}`)) - } - } else if (process.platform === 'freebsd') { - if (process.arch === 'x64') { - try { - return require('./turso.freebsd-x64.node') - } catch (e) { - loadErrors.push(e) - } - try { - return require('@tursodatabase/database-freebsd-x64') - } catch (e) { - loadErrors.push(e) - } - } else if (process.arch === 'arm64') { - try { - return require('./turso.freebsd-arm64.node') - } catch (e) { - loadErrors.push(e) - } - try { - return require('@tursodatabase/database-freebsd-arm64') - } catch (e) { - loadErrors.push(e) - } - } else { - loadErrors.push(new Error(`Unsupported architecture on FreeBSD: ${process.arch}`)) - } - } else if (process.platform === 'linux') { - if (process.arch === 'x64') { - if (isMusl()) { - try { - return require('./turso.linux-x64-musl.node') - } catch (e) { - loadErrors.push(e) - } - try { - return require('@tursodatabase/database-linux-x64-musl') - } catch (e) { - loadErrors.push(e) - } - } else { - try { - return require('./turso.linux-x64-gnu.node') - } catch (e) { - loadErrors.push(e) - } - try { - return require('@tursodatabase/database-linux-x64-gnu') - } catch (e) { - loadErrors.push(e) - } - } - } else if (process.arch === 'arm64') { - if (isMusl()) { - try { - return require('./turso.linux-arm64-musl.node') - } catch (e) { - loadErrors.push(e) - } - try { - return require('@tursodatabase/database-linux-arm64-musl') - } catch (e) { - loadErrors.push(e) - } - } else { - try { - return require('./turso.linux-arm64-gnu.node') - } catch (e) { - loadErrors.push(e) - } - try { - return require('@tursodatabase/database-linux-arm64-gnu') - } catch (e) { - loadErrors.push(e) - } - } - } else if (process.arch === 'arm') { - if (isMusl()) { - try { - return require('./turso.linux-arm-musleabihf.node') - } catch (e) { - loadErrors.push(e) - } - try { - return require('@tursodatabase/database-linux-arm-musleabihf') - } catch (e) { - loadErrors.push(e) - } - } else { - try { - return require('./turso.linux-arm-gnueabihf.node') - } catch (e) { - loadErrors.push(e) - } - try { - return require('@tursodatabase/database-linux-arm-gnueabihf') - } catch (e) { - loadErrors.push(e) - } - } - } else if (process.arch === 'riscv64') { - if (isMusl()) { - try { - return require('./turso.linux-riscv64-musl.node') - } catch (e) { - loadErrors.push(e) - } - try { - return require('@tursodatabase/database-linux-riscv64-musl') - } catch (e) { - loadErrors.push(e) - } - } else { - try { - return require('./turso.linux-riscv64-gnu.node') - } catch (e) { - loadErrors.push(e) - } - try { - return require('@tursodatabase/database-linux-riscv64-gnu') - } catch (e) { - loadErrors.push(e) - } - } - } else if (process.arch === 'ppc64') { - try { - return require('./turso.linux-ppc64-gnu.node') - } catch (e) { - loadErrors.push(e) - } - try { - return require('@tursodatabase/database-linux-ppc64-gnu') - } catch (e) { - loadErrors.push(e) - } - } else if (process.arch === 's390x') { - try { - return require('./turso.linux-s390x-gnu.node') - } catch (e) { - loadErrors.push(e) - } - try { - return require('@tursodatabase/database-linux-s390x-gnu') - } catch (e) { - loadErrors.push(e) - } - } else { - loadErrors.push(new Error(`Unsupported architecture on Linux: ${process.arch}`)) - } - } else if (process.platform === 'openharmony') { - if (process.arch === 'arm64') { - try { - return require('./turso.linux-arm64-ohos.node') - } catch (e) { - loadErrors.push(e) - } - try { - return require('@tursodatabase/database-linux-arm64-ohos') - } catch (e) { - loadErrors.push(e) - } - } else if (process.arch === 'x64') { - try { - return require('./turso.linux-x64-ohos.node') - } catch (e) { - loadErrors.push(e) - } - try { - return require('@tursodatabase/database-linux-x64-ohos') - } catch (e) { - loadErrors.push(e) - } - } else if (process.arch === 'arm') { - try { - return require('./turso.linux-arm-ohos.node') - } catch (e) { - loadErrors.push(e) - } - try { - return require('@tursodatabase/database-linux-arm-ohos') - } catch (e) { - loadErrors.push(e) - } - } else { - loadErrors.push(new Error(`Unsupported architecture on OpenHarmony: ${process.arch}`)) - } - } else { - loadErrors.push(new Error(`Unsupported OS: ${process.platform}, architecture: ${process.arch}`)) - } -} - -nativeBinding = requireNative() - -if (!nativeBinding || process.env.NAPI_RS_FORCE_WASI) { - try { - nativeBinding = require('./turso.wasi.cjs') - } catch (err) { - if (process.env.NAPI_RS_FORCE_WASI) { - loadErrors.push(err) - } - } - if (!nativeBinding) { - try { - nativeBinding = require('@tursodatabase/database-wasm32-wasi') - } catch (err) { - if (process.env.NAPI_RS_FORCE_WASI) { - loadErrors.push(err) - } - } - } -} - -if (!nativeBinding) { - if (loadErrors.length > 0) { - throw new Error( - `Cannot find native binding. ` + - `npm has a bug related to optional dependencies (https://github.com/npm/cli/issues/4828). ` + - 'Please try `npm i` again after removing both package-lock.json and node_modules directory.', - { cause: loadErrors } - ) - } - throw new Error(`Failed to load native binding`) -} - -const { Database, Statement } = nativeBinding -export { Database } -export { Statement } diff --git a/bindings/javascript/package-lock.json b/bindings/javascript/package-lock.json index e8c74d419..551080310 100644 --- a/bindings/javascript/package-lock.json +++ b/bindings/javascript/package-lock.json @@ -1,29 +1,63 @@ { - "name": "@tursodatabase/database", - "version": "0.1.5-pre.3", + "name": "javascript", + "version": "0.1.5-pre.5", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "@tursodatabase/database", - "version": "0.1.5-pre.3", + "version": "0.1.5-pre.5", + "workspaces": [ + "packages/common", + "packages/native", + "packages/browser" + ] + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "dev": true, "license": "MIT", - "devDependencies": { - "@napi-rs/cli": "^3.0.4", - "@napi-rs/wasm-runtime": "^1.0.1", - "ava": "^6.0.1", - "better-sqlite3": "^11.9.1", - "typescript": "^5.9.2" + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" }, "engines": { - "node": ">= 10" + "node": ">=6.9.0" + } + }, + "node_modules/@babel/code-frame/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/@babel/helper-validator-identifier": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz", + "integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" } }, "node_modules/@emnapi/core": { "version": "1.4.5", "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.4.5.tgz", "integrity": "sha512-XsLw1dEOpkSX/WucdqUhPWP7hDxSvZiY+fsUC14h+FtQ2Ifni4znbBt8punRX+Uj2JG/uDb8nEHVKvrVlvdZ5Q==", - "dev": true, "license": "MIT", "dependencies": { "@emnapi/wasi-threads": "1.0.4", @@ -34,7 +68,6 @@ "version": "1.4.5", "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.5.tgz", "integrity": "sha512-++LApOtY0pEEz1zrd9vy1/zXVaVJJ/EbAF3u0fXIzPJEDtnITsBGbbK0EkM72amhl/R5b+5xx0Y/QhcVOpuulg==", - "dev": true, "license": "MIT", "dependencies": { "tslib": "^2.4.0" @@ -44,12 +77,28 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.0.4.tgz", "integrity": "sha512-PJR+bOmMOPH8AtcTGAyYNiuJ3/Fcoj2XN/gBEWzDIKh254XO+mM9XoXHk5GNEhodxeMznbg7BlRojVbKN+gC6g==", - "dev": true, "license": "MIT", "dependencies": { "tslib": "^2.4.0" } }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.9.tgz", + "integrity": "sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@inquirer/checkbox": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.2.0.tgz", @@ -125,16 +174,6 @@ } } }, - "node_modules/@inquirer/core/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/@inquirer/core/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -454,88 +493,17 @@ } } }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@isaacs/cliui/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", "dev": true, "license": "MIT" }, - "node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@isaacs/fs-minipass": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", - "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", - "dev": true, - "license": "ISC", - "dependencies": { - "minipass": "^7.0.4" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@mapbox/node-pre-gyp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-2.0.0.tgz", - "integrity": "sha512-llMXd39jtP0HpQLVI37Bf1m2ADlEb35GYSh1SDSLsBhR+5iCxiNGlT31yqbNtVHygHAtMy6dWFERpU2JgufhPg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "consola": "^3.2.3", - "detect-libc": "^2.0.0", - "https-proxy-agent": "^7.0.5", - "node-fetch": "^2.6.7", - "nopt": "^8.0.0", - "semver": "^7.5.3", - "tar": "^7.4.0" - }, - "bin": { - "node-pre-gyp": "bin/node-pre-gyp" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/@napi-rs/cli": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@napi-rs/cli/-/cli-3.0.4.tgz", - "integrity": "sha512-ilbCI69DVDQcIUSUB504LM1+Nhvo0jKycWAzzPJ22YwUoWrru/w0+V5sfjPINgkshQ4Ykv+oZOJXk9Kg1ZBUvg==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@napi-rs/cli/-/cli-3.1.5.tgz", + "integrity": "sha512-Wn6ZPw27qJiEWglGjkaAa70AHuLtyPya6FvjINYJ5U20uvbRhoB0Ta2+bFTAFfUb9R+wvuFvog9JQdy65OmFAQ==", "dev": true, "license": "MIT", "dependencies": { @@ -547,9 +515,9 @@ "colorette": "^2.0.20", "debug": "^4.4.0", "emnapi": "^1.4.0", + "es-toolkit": "^1.39.8", "find-up": "^7.0.0", "js-yaml": "^4.1.0", - "lodash-es": "^4.17.21", "semver": "^7.7.1", "typanion": "^3.14.0" }, @@ -675,108 +643,6 @@ "@napi-rs/lzma-win32-x64-msvc": "1.4.4" } }, - "node_modules/@napi-rs/lzma-android-arm-eabi": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/@napi-rs/lzma-android-arm-eabi/-/lzma-android-arm-eabi-1.4.4.tgz", - "integrity": "sha512-smZtN41ebtYw+vxn1q3IXhns1hUzFNUcgHxknZKFQSKaybYZ4KxMiiBIw5UqJ9rw1dkaHqokcC1YeAfu8vfG2A==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/lzma-android-arm64": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/@napi-rs/lzma-android-arm64/-/lzma-android-arm64-1.4.4.tgz", - "integrity": "sha512-s+h9bM3Z31FL0IPfWF4kBCebWxJBtpFvje6ikzmeUg1/jjWAP81IJC5j75zz5TEWt+Zf3Bip0uVlQhCZmqlpKA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/lzma-darwin-arm64": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/@napi-rs/lzma-darwin-arm64/-/lzma-darwin-arm64-1.4.4.tgz", - "integrity": "sha512-aF5wxA0SFlRalxeyz7TpmFuztHlG9D0qew+1gz0tiRs4gituT3CCsR0PSBZ2LbalTY/7RqmYP4ssLQus+p8tqg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/lzma-darwin-x64": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/@napi-rs/lzma-darwin-x64/-/lzma-darwin-x64-1.4.4.tgz", - "integrity": "sha512-80gD9kvXPPBz6V4C7SXcPo0o7ySlneDVRpebAHN1DubIEwhdrMFuqmtaATwT5MTraZSrQ4CHF275MQuwiHtlGw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/lzma-freebsd-x64": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/@napi-rs/lzma-freebsd-x64/-/lzma-freebsd-x64-1.4.4.tgz", - "integrity": "sha512-wd+jwYQRIzkGtUvInYLWSrqRtDatIvwNm/w9k43f+oABBsnP4veJkyKGGm4SQQa35Ki8IXVzYdGTa4eSTi+Org==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/lzma-linux-arm-gnueabihf": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/@napi-rs/lzma-linux-arm-gnueabihf/-/lzma-linux-arm-gnueabihf-1.4.4.tgz", - "integrity": "sha512-KiMgBugjFQfgeZTebuBVHL8ta/nZ2cfzd0Jge0e0y/WX/p7ZkVyCox/TTu9EU2H9OeBAFKTRmIDoqhHlBbkqyA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, "node_modules/@napi-rs/lzma-linux-arm64-gnu": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/@napi-rs/lzma-linux-arm64-gnu/-/lzma-linux-arm64-gnu-1.4.4.tgz", @@ -811,91 +677,6 @@ "node": ">= 10" } }, - "node_modules/@napi-rs/lzma-linux-ppc64-gnu": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/@napi-rs/lzma-linux-ppc64-gnu/-/lzma-linux-ppc64-gnu-1.4.4.tgz", - "integrity": "sha512-QzNVcCdq6j4LYOtLUDEyE9wg8tY8kmbQ6TZrqjYQUD2nebTW24lmzFhdeI3xzUzVN5rRt4js1UnL1cPCT5HrSw==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/lzma-linux-riscv64-gnu": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/@napi-rs/lzma-linux-riscv64-gnu/-/lzma-linux-riscv64-gnu-1.4.4.tgz", - "integrity": "sha512-7jpyKpBX0LpklkmGBzz1cQJ/QRN+E6h1xSZVeN6KCtLBrCd6LCX3owZMRzSYmdpI6Zr30DrWo0HOUZiKMzgzBg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/lzma-linux-s390x-gnu": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/@napi-rs/lzma-linux-s390x-gnu/-/lzma-linux-s390x-gnu-1.4.4.tgz", - "integrity": "sha512-ngUxVZIytn2UHY92RnijtT11VhWO32mfa1LFX03GWMWdQl50bV/IqcZR0WYRWlBCd7DZrOf16AY2IR/lwovE7A==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/lzma-linux-x64-gnu": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/@napi-rs/lzma-linux-x64-gnu/-/lzma-linux-x64-gnu-1.4.4.tgz", - "integrity": "sha512-mUGH8hpWJU4FXhn61cD7sHTUEBiWU5JYOhh6ErCIZ0BOoBH/0kYPptfqvJA6G9EfVIcfbtYKxJYYtFC5sbf+eA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/lzma-linux-x64-musl": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/@napi-rs/lzma-linux-x64-musl/-/lzma-linux-x64-musl-1.4.4.tgz", - "integrity": "sha512-ysM4mYSfWGO2h8YZVn0GH7zMZX42hU0h7IomC4/oBJmAk5BIlOGnRB8XQmyz1A7neSi6aByjAlZmW4CrZlI9Uw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, "node_modules/@napi-rs/lzma-wasm32-wasi": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/@napi-rs/lzma-wasm32-wasi/-/lzma-wasm32-wasi-1.4.4.tgz", @@ -913,57 +694,6 @@ "node": ">=14.0.0" } }, - "node_modules/@napi-rs/lzma-win32-arm64-msvc": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/@napi-rs/lzma-win32-arm64-msvc/-/lzma-win32-arm64-msvc-1.4.4.tgz", - "integrity": "sha512-GqoJu7iL7OTqkBQGLps7rXQHZ5sdcZF7tOY06rlYO03ZNkUCjhNpmkuUsPXVnGstqgoGwzMNW6TcSsO/YWotEw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/lzma-win32-ia32-msvc": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/@napi-rs/lzma-win32-ia32-msvc/-/lzma-win32-ia32-msvc-1.4.4.tgz", - "integrity": "sha512-cnExNqWKl0JkLcKlFVuqUrTuQsYP8nstWGT3fz7mPhgqHFOgGmd1l9tDFhqgul7Kt0QTddZRbKl6jlkV7DjSQw==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/lzma-win32-x64-msvc": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/@napi-rs/lzma-win32-x64-msvc/-/lzma-win32-x64-msvc-1.4.4.tgz", - "integrity": "sha512-15SoQgMgktF73ZnLQPkzCwtxyQ+4VuD8n5Puis1H48QRjUNnXXpqTGFyWdLPdd14vcxbndgcYvJtSjOXTfNHiw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, "node_modules/@napi-rs/tar": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@napi-rs/tar/-/tar-1.0.0.tgz", @@ -992,108 +722,6 @@ "@napi-rs/tar-win32-x64-msvc": "1.0.0" } }, - "node_modules/@napi-rs/tar-android-arm-eabi": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@napi-rs/tar-android-arm-eabi/-/tar-android-arm-eabi-1.0.0.tgz", - "integrity": "sha512-oEntU16IkWykPJnSwv/VIICzIt2SwEsz45z2Ab+EXOas10EB+pu0z31AiSNI5pr1CaJcadbf1JGMI9aOtbAuRQ==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/tar-android-arm64": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@napi-rs/tar-android-arm64/-/tar-android-arm64-1.0.0.tgz", - "integrity": "sha512-b2X7nQ/wH2VGzzl4KhVOR/gHqxIuqrUjMY8VKJYxAGdCrmUPRfc47kersiu6DG706kSv9T+BxeeUQvwqnXZRXQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/tar-darwin-arm64": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@napi-rs/tar-darwin-arm64/-/tar-darwin-arm64-1.0.0.tgz", - "integrity": "sha512-m1Ug1452/DOUbJGSuJuHRTUCBQOXY0arGqXCHuSiaQhBQQjgBhlbHWCv291gV8CytFYd5lvSyiG2gFUU26Qd7A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/tar-darwin-x64": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@napi-rs/tar-darwin-x64/-/tar-darwin-x64-1.0.0.tgz", - "integrity": "sha512-1RiC53g1y4pxX7P2L9sbZcqsw6dfXvGnTNwXHDjg4ATZncZa7uoPUWa7aHAGcQm8ZBO4P0ICt2SHOepstDWWTg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/tar-freebsd-x64": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@napi-rs/tar-freebsd-x64/-/tar-freebsd-x64-1.0.0.tgz", - "integrity": "sha512-uLaYn+eO3ZY2ojbohdlRFcuqYP+j2alovtuLdFvCzzsArg4DSnmcJvEQ+I4l99lfyThYB1c8GA64oxSOfmn/UA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/tar-linux-arm-gnueabihf": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@napi-rs/tar-linux-arm-gnueabihf/-/tar-linux-arm-gnueabihf-1.0.0.tgz", - "integrity": "sha512-PhGIaT45i1Fj5iY6NiWYTLPUOHb7rXiwnqKhco+IXOeIclaGcEVoAbhrLiLGQrfv9viLdyhzAxECoOr+zKnApw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, "node_modules/@napi-rs/tar-linux-arm64-gnu": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@napi-rs/tar-linux-arm64-gnu/-/tar-linux-arm64-gnu-1.0.0.tgz", @@ -1128,74 +756,6 @@ "node": ">= 10" } }, - "node_modules/@napi-rs/tar-linux-ppc64-gnu": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@napi-rs/tar-linux-ppc64-gnu/-/tar-linux-ppc64-gnu-1.0.0.tgz", - "integrity": "sha512-IbB4I8RFcvKI/zGsboUQPmlKoXfXgNOMiJw7Cbe7T1OBeYzDy6n/yEUEaG4zIbocxqjRVsF4ElrW1V/0Ihlqzg==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/tar-linux-s390x-gnu": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@napi-rs/tar-linux-s390x-gnu/-/tar-linux-s390x-gnu-1.0.0.tgz", - "integrity": "sha512-Tl4HSo07u3TLsNQ4KEVfYKdHVNfF/k0o5KQlyGnePiO34Kb+NfaqSKMspjSkrmXKEc0PjB+u9af3BZdTUwml4Q==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/tar-linux-x64-gnu": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@napi-rs/tar-linux-x64-gnu/-/tar-linux-x64-gnu-1.0.0.tgz", - "integrity": "sha512-Xe57Yz4MKSeG6HGECiIHuBKFwAuqs2fzwblTdMd1CoSgaaUc/K/dKTDWZwPtjC0Hh5pM86K0WZuwggbsjmFGNg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/tar-linux-x64-musl": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@napi-rs/tar-linux-x64-musl/-/tar-linux-x64-musl-1.0.0.tgz", - "integrity": "sha512-VA4RXspXyelNAtaFEf2ZLnTYXRILVlH20OGV0oqzuUcQzpwEwK2cJbYtYHK+yCYpxrNbEGsAwN+12LYJMW+NlA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, "node_modules/@napi-rs/tar-wasm32-wasi": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@napi-rs/tar-wasm32-wasi/-/tar-wasm32-wasi-1.0.0.tgz", @@ -1213,62 +773,10 @@ "node": ">=14.0.0" } }, - "node_modules/@napi-rs/tar-win32-arm64-msvc": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@napi-rs/tar-win32-arm64-msvc/-/tar-win32-arm64-msvc-1.0.0.tgz", - "integrity": "sha512-VdUjZK8jh6mvGRiurK3ms6Yt2hbBbtYjzKCn78Mnme2KGC585Kx1jXl7HShvreCgqh3r0162OSygoE7d/I0Jlw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/tar-win32-ia32-msvc": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@napi-rs/tar-win32-ia32-msvc/-/tar-win32-ia32-msvc-1.0.0.tgz", - "integrity": "sha512-8d/4iRXROPXLoe+4FEqXkpgP2KD9A45VUf76WfT6nXZwzQuoh+9WCJNRPVs5vfXV1SMnG9Z32WNc2ivCq0+HZw==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/tar-win32-x64-msvc": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@napi-rs/tar-win32-x64-msvc/-/tar-win32-x64-msvc-1.0.0.tgz", - "integrity": "sha512-HHtL1g0niVa4xDvyfi9wQtCTDDKkhDlaOb3bmayTqWs29mk+pcVHBST3OdXaaViSaduqdG9meosU5sOj5iKQAQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, "node_modules/@napi-rs/wasm-runtime": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.0.1.tgz", - "integrity": "sha512-KVlQ/jgywZpixGCKMNwxStmmbYEMyokZpCf2YuIChhfJA2uqfAKNEM8INz7zzTo55iEXfBhIIs3VqYyqzDLj8g==", - "dev": true, + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.0.3.tgz", + "integrity": "sha512-rZxtMsLwjdXkMUGC3WwsPwLNVqVqnTJT6MNIB6e+5fhMcSCPP0AOsNWuMQ5mdCq6HNjs/ZeWAEchpqeprqBD2Q==", "license": "MIT", "dependencies": { "@emnapi/core": "^1.4.5", @@ -1301,91 +809,6 @@ "@napi-rs/wasm-tools-win32-x64-msvc": "1.0.0" } }, - "node_modules/@napi-rs/wasm-tools-android-arm-eabi": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-tools-android-arm-eabi/-/wasm-tools-android-arm-eabi-1.0.0.tgz", - "integrity": "sha512-Ks0hplmrYatIjSi8XeTObCi0x13AOQD41IQXpBjrz+UK71gDkbxyLWO7B/ckuels3mC1DW3OCQCv+q0lPnaG/A==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/wasm-tools-android-arm64": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-tools-android-arm64/-/wasm-tools-android-arm64-1.0.0.tgz", - "integrity": "sha512-Ppu1/YGLSC/ohkOA8R5YfDh1dCuCHWJObu/BTorAY55YDXIiWy400CoungbYwoRT53K+ixNrg8/zRHnpuqwkRg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/wasm-tools-darwin-arm64": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-tools-darwin-arm64/-/wasm-tools-darwin-arm64-1.0.0.tgz", - "integrity": "sha512-EUU7NvmmKASMLecu7hUHhv9XN2Thf8j+2/zCCMuFuAAlY+eZiOVfrajbZ/RE8CZ4oyfkb0bWFg/CQcmcXAatTw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/wasm-tools-darwin-x64": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-tools-darwin-x64/-/wasm-tools-darwin-x64-1.0.0.tgz", - "integrity": "sha512-hlX21sqy0AEnmn2abarmCXV3fpyIQN+fKqeHNuawti9ZpaJCL6gZCtUGqpUxURjXNjXSI8rywInJE2YmeVQSJQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/wasm-tools-freebsd-x64": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-tools-freebsd-x64/-/wasm-tools-freebsd-x64-1.0.0.tgz", - "integrity": "sha512-T9SOSfIgrdEGQzzquKMOfD3PF6TxG5hL2o5voZtLUALA0yjO+GnpFyv8tAcxKYd7ngWzzK5Uwk7e1z9PcsQZMg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 10" - } - }, "node_modules/@napi-rs/wasm-tools-linux-arm64-gnu": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@napi-rs/wasm-tools-linux-arm64-gnu/-/wasm-tools-linux-arm64-gnu-1.0.0.tgz", @@ -1420,40 +843,6 @@ "node": ">= 10" } }, - "node_modules/@napi-rs/wasm-tools-linux-x64-gnu": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-tools-linux-x64-gnu/-/wasm-tools-linux-x64-gnu-1.0.0.tgz", - "integrity": "sha512-wpRkiy0QBM/zpaGAn5I1HfddQul0vGrdlindT2UHtOYK1zvam524M6LJXBtmhBkXS5a4F2HZiZXns8Wuc7dq4w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/wasm-tools-linux-x64-musl": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-tools-linux-x64-musl/-/wasm-tools-linux-x64-musl-1.0.0.tgz", - "integrity": "sha512-Ua94ruWB18uKyIz/nj+by2ZxfBbFzbqiiD564ocBHGbrUffpR6Us74uVwxO7rImc/WvCfJqap9ezqmaTvmK7SA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, "node_modules/@napi-rs/wasm-tools-wasm32-wasi": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@napi-rs/wasm-tools-wasm32-wasi/-/wasm-tools-wasm32-wasi-1.0.0.tgz", @@ -1471,95 +860,6 @@ "node": ">=14.0.0" } }, - "node_modules/@napi-rs/wasm-tools-win32-arm64-msvc": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-tools-win32-arm64-msvc/-/wasm-tools-win32-arm64-msvc-1.0.0.tgz", - "integrity": "sha512-1kv+DM7z6c9OLcjMtO1/kfdxS5hwXtW1OLIHBU41dtKz5jD3quapYrCjB7AVEZh/JVM765UaLOl31huVucJjRw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/wasm-tools-win32-ia32-msvc": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-tools-win32-ia32-msvc/-/wasm-tools-win32-ia32-msvc-1.0.0.tgz", - "integrity": "sha512-OwcyXtU2Zi3YVHYjmomM3u7jRNPY1j+IPehqCVEqd60jOTOXRZNPGoAvOC7Lw6HX/RGzOJnIcJZbVfKrz5WN1g==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/wasm-tools-win32-x64-msvc": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-tools-win32-x64-msvc/-/wasm-tools-win32-x64-msvc-1.0.0.tgz", - "integrity": "sha512-xat6gnp/G/WCe6U6HKzawotz9zpqsM5a+Dx+S0MPX4AKP7+oztC2/6tkp8KtOPT2bMRMekNntXadHKk0XqW61Q==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/@octokit/auth-token": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-6.0.0.tgz", @@ -1726,63 +1026,120 @@ "@octokit/openapi-types": "^25.1.0" } }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "node_modules/@polka/url": { + "version": "1.0.0-next.29", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz", + "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.50.1.tgz", + "integrity": "sha512-2AbMhFFkTo6Ptna1zO7kAXXDLi7H9fGTbVaIq2AAYO7yzcAsuTNWPHhb2aTA6GPiP+JXh85Y8CiS54iZoj4opw==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", "optional": true, - "engines": { - "node": ">=14" - } + "os": [ + "linux" + ] }, - "node_modules/@rollup/pluginutils": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.2.0.tgz", - "integrity": "sha512-qWJ2ZTbmumwiLFomfzTyt5Kng4hwPi9rwCYN4SHb6eaRU1KNO4ccxINHr/VhH4GgPlt1XfSTLX2LBTme8ne4Zw==", + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.50.1.tgz", + "integrity": "sha512-Cgef+5aZwuvesQNw9eX7g19FfKX5/pQRIyhoXLCiBOrWopjo7ycfB292TX9MDcDijiuIJlx1IzJz3IoCPfqs9w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@testing-library/dom": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz", + "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==", "dev": true, "license": "MIT", "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^4.0.2" + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.3.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "picocolors": "1.1.1", + "pretty-format": "^27.0.2" }, "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } + "node": ">=18" } }, - "node_modules/@sindresorhus/merge-streams": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", - "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", + "node_modules/@testing-library/user-event": { + "version": "14.6.1", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.6.1.tgz", + "integrity": "sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==", "dev": true, "license": "MIT", "engines": { - "node": ">=18" + "node": ">=12", + "npm": ">=6" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "@testing-library/dom": ">=7.21.4" } }, + "node_modules/@tursodatabase/database": { + "resolved": "packages/native", + "link": true + }, + "node_modules/@tursodatabase/database-browser": { + "resolved": "packages/browser", + "link": true + }, + "node_modules/@tursodatabase/database-common": { + "resolved": "packages/common", + "link": true + }, "node_modules/@tybys/wasm-util": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.0.tgz", "integrity": "sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ==", - "dev": true, "license": "MIT", "dependencies": { "tslib": "^2.4.0" } }, + "node_modules/@types/aria-query": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/chai": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.2.tgz", + "integrity": "sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/deep-eql": "*" + } + }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/estree": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", @@ -1790,87 +1147,175 @@ "dev": true, "license": "MIT" }, - "node_modules/@vercel/nft": { - "version": "0.29.4", - "resolved": "https://registry.npmjs.org/@vercel/nft/-/nft-0.29.4.tgz", - "integrity": "sha512-6lLqMNX3TuycBPABycx7A9F1bHQR7kiQln6abjFbPrf5C/05qHM9M5E4PeTE59c7z8g6vHnx1Ioihb2AQl7BTA==", + "node_modules/@types/node": { + "version": "24.3.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.3.1.tgz", + "integrity": "sha512-3vXmQDXy+woz+gnrTvuvNrPzekOi+Ds0ReMxw0LzBiK3a+1k0kQn9f2NWk+lgD4rJehFUmYy2gMhJ2ZI+7YP9g==", "dev": true, "license": "MIT", "dependencies": { - "@mapbox/node-pre-gyp": "^2.0.0", - "@rollup/pluginutils": "^5.1.3", - "acorn": "^8.6.0", - "acorn-import-attributes": "^1.9.5", - "async-sema": "^3.1.1", - "bindings": "^1.4.0", - "estree-walker": "2.0.2", - "glob": "^10.4.5", - "graceful-fs": "^4.2.9", - "node-gyp-build": "^4.2.2", - "picomatch": "^4.0.2", - "resolve-from": "^5.0.0" - }, - "bin": { - "nft": "out/cli.js" - }, - "engines": { - "node": ">=18" + "undici-types": "~7.10.0" } }, - "node_modules/abbrev": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-3.0.1.tgz", - "integrity": "sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==", - "dev": true, - "license": "ISC", - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "node_modules/@vitest/browser": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/browser/-/browser-3.2.4.tgz", + "integrity": "sha512-tJxiPrWmzH8a+w9nLKlQMzAKX/7VjFs50MWgcAj7p9XQ7AQ9/35fByFYptgPELyLw+0aixTnC4pUWV+APcZ/kw==", "dev": true, "license": "MIT", - "bin": { - "acorn": "bin/acorn" + "dependencies": { + "@testing-library/dom": "^10.4.0", + "@testing-library/user-event": "^14.6.1", + "@vitest/mocker": "3.2.4", + "@vitest/utils": "3.2.4", + "magic-string": "^0.30.17", + "sirv": "^3.0.1", + "tinyrainbow": "^2.0.0", + "ws": "^8.18.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-import-attributes": { - "version": "1.9.5", - "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", - "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", - "dev": true, - "license": "MIT", "peerDependencies": { - "acorn": "^8" + "playwright": "*", + "vitest": "3.2.4", + "webdriverio": "^7.0.0 || ^8.0.0 || ^9.0.0" + }, + "peerDependenciesMeta": { + "playwright": { + "optional": true + }, + "safaridriver": { + "optional": true + }, + "webdriverio": { + "optional": true + } } }, - "node_modules/acorn-walk": { - "version": "8.3.4", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", - "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "node_modules/@vitest/expect": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.4.tgz", + "integrity": "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==", "dev": true, "license": "MIT", "dependencies": { - "acorn": "^8.11.0" + "@types/chai": "^5.2.2", + "@vitest/spy": "3.2.4", + "@vitest/utils": "3.2.4", + "chai": "^5.2.0", + "tinyrainbow": "^2.0.0" }, - "engines": { - "node": ">=0.4.0" + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/agent-base": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", - "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "node_modules/@vitest/mocker": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.4.tgz", + "integrity": "sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==", "dev": true, "license": "MIT", - "engines": { - "node": ">= 14" + "dependencies": { + "@vitest/spy": "3.2.4", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.17" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/mocker/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/@vitest/pretty-format": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.4.tgz", + "integrity": "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.4.tgz", + "integrity": "sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "3.2.4", + "pathe": "^2.0.3", + "strip-literal": "^3.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.4.tgz", + "integrity": "sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "3.2.4", + "magic-string": "^0.30.17", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.4.tgz", + "integrity": "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^4.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.4.tgz", + "integrity": "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "3.2.4", + "loupe": "^3.1.4", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" } }, "node_modules/ansi-escapes": { @@ -1903,172 +1348,48 @@ } }, "node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "license": "MIT", "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" + "node": ">=8" } }, "node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, "license": "MIT", "engines": { - "node": ">=12" + "node": ">=10" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "sprintf-js": "~1.0.2" + "dequal": "^2.0.3" } }, - "node_modules/array-find-index": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", - "integrity": "sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arrgv": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/arrgv/-/arrgv-1.0.2.tgz", - "integrity": "sha512-a4eg4yhp7mmruZDQFqVMlxNRFGi/i1r87pt8SDHy0/I8PqSXoUTlWZRdAZo0VXgvEARcujbtTk8kiZRi1uDGRw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/arrify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-3.0.0.tgz", - "integrity": "sha512-tLkvA81vQG/XqE2mjDkGQHoOINtMHtysSnemrmoGe6PydDPMRbVugqyk4A6V/WDWEfm3l+0d8anA9r8cv/5Jaw==", + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", "dev": true, "license": "MIT", "engines": { "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/async-sema": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/async-sema/-/async-sema-3.1.1.tgz", - "integrity": "sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg==", - "dev": true, - "license": "MIT" - }, - "node_modules/ava": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/ava/-/ava-6.4.1.tgz", - "integrity": "sha512-vxmPbi1gZx9zhAjHBgw81w/iEDKcrokeRk/fqDTyA2DQygZ0o+dUGRHFOtX8RA5N0heGJTTsIk7+xYxitDb61Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vercel/nft": "^0.29.4", - "acorn": "^8.15.0", - "acorn-walk": "^8.3.4", - "ansi-styles": "^6.2.1", - "arrgv": "^1.0.2", - "arrify": "^3.0.0", - "callsites": "^4.2.0", - "cbor": "^10.0.9", - "chalk": "^5.4.1", - "chunkd": "^2.0.1", - "ci-info": "^4.3.0", - "ci-parallel-vars": "^1.0.1", - "cli-truncate": "^4.0.0", - "code-excerpt": "^4.0.0", - "common-path-prefix": "^3.0.0", - "concordance": "^5.0.4", - "currently-unhandled": "^0.4.1", - "debug": "^4.4.1", - "emittery": "^1.2.0", - "figures": "^6.1.0", - "globby": "^14.1.0", - "ignore-by-default": "^2.1.0", - "indent-string": "^5.0.0", - "is-plain-object": "^5.0.0", - "is-promise": "^4.0.0", - "matcher": "^5.0.0", - "memoize": "^10.1.0", - "ms": "^2.1.3", - "p-map": "^7.0.3", - "package-config": "^5.0.0", - "picomatch": "^4.0.2", - "plur": "^5.1.0", - "pretty-ms": "^9.2.0", - "resolve-cwd": "^3.0.0", - "stack-utils": "^2.0.6", - "strip-ansi": "^7.1.0", - "supertap": "^3.0.1", - "temp-dir": "^3.0.0", - "write-file-atomic": "^6.0.0", - "yargs": "^17.7.2" - }, - "bin": { - "ava": "entrypoints/cli.mjs" - }, - "engines": { - "node": "^18.18 || ^20.8 || ^22 || ^23 || >=24" - }, - "peerDependencies": { - "@ava/typescript": "*" - }, - "peerDependenciesMeta": { - "@ava/typescript": { - "optional": true - } - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, - "license": "MIT" - }, - "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/before-after-hook": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-4.0.0.tgz", @@ -2076,132 +1397,31 @@ "dev": true, "license": "Apache-2.0" }, - "node_modules/better-sqlite3": { - "version": "11.10.0", - "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-11.10.0.tgz", - "integrity": "sha512-EwhOpyXiOEL/lKzHz9AW1msWFNzGc/z+LzeB3/jnFJpxu+th2yqvzsSWas1v9jgs9+xiXJcD5A8CJxAG2TaghQ==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "bindings": "^1.5.0", - "prebuild-install": "^7.1.1" - } - }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", "dev": true, "license": "MIT", - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, - "node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "node_modules/blueimp-md5": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.19.0.tgz", - "integrity": "sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w==", - "dev": true, - "license": "MIT" - }, - "node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "license": "MIT", - "dependencies": { - "fill-range": "^7.1.1" - }, "engines": { "node": ">=8" } }, - "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/callsites": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-4.2.0.tgz", - "integrity": "sha512-kfzR4zzQtAE9PC7CzZsjl3aBNbXWuXiSeOCdLcPpBfGW8YuCqQHcRPFDbr/BPVmd3EEPVpuFzLyuT/cUhPr4OQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cbor": { - "version": "10.0.9", - "resolved": "https://registry.npmjs.org/cbor/-/cbor-10.0.9.tgz", - "integrity": "sha512-KEWYehb/vJkRmigctVQLsz73Us2RNnITo/wOwQV5AtZpLGH1r2PPlsNHdsX460YuHZCyhLklbYzAOuJfOeg34Q==", + "node_modules/chai": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", + "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", "dev": true, "license": "MIT", "dependencies": { - "nofilter": "^3.0.2" + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" }, "engines": { - "node": ">=20" - } - }, - "node_modules/chalk": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", - "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": ">=18" } }, "node_modules/chardet": { @@ -2211,61 +1431,14 @@ "dev": true, "license": "MIT" }, - "node_modules/chownr": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", - "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", - "dev": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - }, - "node_modules/chunkd": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/chunkd/-/chunkd-2.0.1.tgz", - "integrity": "sha512-7d58XsFmOq0j6el67Ug9mHf9ELUXsQXYJBkyxhH/k+6Ke0qXRnv0kbemx+Twc6fRJ07C49lcbdgm9FL1Ei/6SQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/ci-info": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.0.tgz", - "integrity": "sha512-l+2bNRMiQgcfILUi33labAZYIWlH1kWDp+ecNo5iisRKrbm0xcRyCww71/YU0Fkw0mAFpz9bJayXPjey6vkmaQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/ci-parallel-vars": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ci-parallel-vars/-/ci-parallel-vars-1.0.1.tgz", - "integrity": "sha512-uvzpYrpmidaoxvIQHM+rKSrigjOe9feHYbw4uOI2gdfe1C3xIlxO+kVXq83WQWNniTf8bAxVpy+cQeFQsMERKg==", - "dev": true, - "license": "MIT" - }, - "node_modules/cli-truncate": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", - "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", + "node_modules/check-error": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", + "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", "dev": true, "license": "MIT", - "dependencies": { - "slice-ansi": "^5.0.0", - "string-width": "^7.0.0" - }, "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 16" } }, "node_modules/cli-width": { @@ -2294,123 +1467,6 @@ "typanion": "*" } }, - "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/cliui/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/cliui/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/cliui/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==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/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/cliui/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/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==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/code-excerpt": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/code-excerpt/-/code-excerpt-4.0.0.tgz", - "integrity": "sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA==", - "dev": true, - "license": "MIT", - "dependencies": { - "convert-to-spaces": "^2.0.1" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -2438,94 +1494,6 @@ "dev": true, "license": "MIT" }, - "node_modules/common-path-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", - "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", - "dev": true, - "license": "ISC" - }, - "node_modules/concordance": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/concordance/-/concordance-5.0.4.tgz", - "integrity": "sha512-OAcsnTEYu1ARJqWVGwf4zh4JDfHZEaSNlNccFmt8YjB2l/n19/PF2viLINHc57vO4FKIAFl2FWASIGZZWZ2Kxw==", - "dev": true, - "license": "ISC", - "dependencies": { - "date-time": "^3.1.0", - "esutils": "^2.0.3", - "fast-diff": "^1.2.0", - "js-string-escape": "^1.0.1", - "lodash": "^4.17.15", - "md5-hex": "^3.0.1", - "semver": "^7.3.2", - "well-known-symbols": "^2.0.0" - }, - "engines": { - "node": ">=10.18.0 <11 || >=12.14.0 <13 || >=14" - } - }, - "node_modules/consola": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", - "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^14.18.0 || >=16.10.0" - } - }, - "node_modules/convert-to-spaces": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/convert-to-spaces/-/convert-to-spaces-2.0.1.tgz", - "integrity": "sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, - "node_modules/cross-spawn": { - "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": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/currently-unhandled": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", - "integrity": "sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-find-index": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/date-time": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/date-time/-/date-time-3.1.0.tgz", - "integrity": "sha512-uqCUKXE5q1PNBXjPqvwhwJf9SwMoAHBgWJ6DcrnS5o+W2JOiIILl0JEdVD8SGujrNS02GGxgwAg2PN2zONgtjg==", - "dev": true, - "license": "MIT", - "dependencies": { - "time-zone": "^1.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/debug": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", @@ -2544,62 +1512,33 @@ } } }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", "dev": true, "license": "MIT", "engines": { - "node": ">=4.0.0" + "node": ">=6" } }, - "node_modules/detect-libc": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", - "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=6" } }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "node_modules/dom-accessibility-api": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", "dev": true, "license": "MIT" }, - "node_modules/emittery": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-1.2.0.tgz", - "integrity": "sha512-KxdRyyFcS85pH3dnU8Y5yFUm2YJdaHwcBZWrfG8o89ZY9a13/f9itbN+YG3ELbBo9Pg5zvIozstmuV8bX13q6g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" - } - }, "node_modules/emnapi": { "version": "1.4.5", "resolved": "https://registry.npmjs.org/emnapi/-/emnapi-1.4.5.tgz", @@ -2615,85 +1554,74 @@ } } }, - "node_modules/emoji-regex": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", - "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", "dev": true, "license": "MIT" }, - "node_modules/end-of-stream": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", - "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "node_modules/es-toolkit": { + "version": "1.39.10", + "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.39.10.tgz", + "integrity": "sha512-E0iGnTtbDhkeczB0T+mxmoVlT4YNweEKBLq7oaU4p11mecdsZpNWOglI4895Vh4usbQ+LsJiuLuI2L0Vdmfm2w==", "dev": true, "license": "MIT", - "dependencies": { - "once": "^1.4.0" - } + "workspaces": [ + "docs", + "benchmarks" + ] }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "node_modules/esbuild": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.9.tgz", + "integrity": "sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g==", "dev": true, + "hasInstallScript": true, "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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" + "esbuild": "bin/esbuild" }, "engines": { - "node": ">=4" + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.9", + "@esbuild/android-arm": "0.25.9", + "@esbuild/android-arm64": "0.25.9", + "@esbuild/android-x64": "0.25.9", + "@esbuild/darwin-arm64": "0.25.9", + "@esbuild/darwin-x64": "0.25.9", + "@esbuild/freebsd-arm64": "0.25.9", + "@esbuild/freebsd-x64": "0.25.9", + "@esbuild/linux-arm": "0.25.9", + "@esbuild/linux-arm64": "0.25.9", + "@esbuild/linux-ia32": "0.25.9", + "@esbuild/linux-loong64": "0.25.9", + "@esbuild/linux-mips64el": "0.25.9", + "@esbuild/linux-ppc64": "0.25.9", + "@esbuild/linux-riscv64": "0.25.9", + "@esbuild/linux-s390x": "0.25.9", + "@esbuild/linux-x64": "0.25.9", + "@esbuild/netbsd-arm64": "0.25.9", + "@esbuild/netbsd-x64": "0.25.9", + "@esbuild/openbsd-arm64": "0.25.9", + "@esbuild/openbsd-x64": "0.25.9", + "@esbuild/openharmony-arm64": "0.25.9", + "@esbuild/sunos-x64": "0.25.9", + "@esbuild/win32-arm64": "0.25.9", + "@esbuild/win32-ia32": "0.25.9", + "@esbuild/win32-x64": "0.25.9" } }, - "node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "node_modules/expect-type": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.2.tgz", + "integrity": "sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==", "dev": true, - "license": "MIT" - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "license": "BSD-2-Clause", + "license": "Apache-2.0", "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-template": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", - "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", - "dev": true, - "license": "(MIT OR WTFPL)", - "engines": { - "node": ">=6" + "node": ">=12.0.0" } }, "node_modules/external-editor": { @@ -2728,74 +1656,22 @@ ], "license": "MIT" }, - "node_modules/fast-diff": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", - "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/fast-glob": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", "dev": true, "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.8" - }, "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fastq": { - "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/figures": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-6.1.0.tgz", - "integrity": "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-unicode-supported": "^2.0.0" + "node": ">=12.0.0" }, - "engines": { - "node": ">=18" + "peerDependencies": { + "picomatch": "^3 || ^4" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } } }, "node_modules/find-up": { @@ -2816,19 +1692,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/find-up-simple": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.1.tgz", - "integrity": "sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/find-up/node_modules/unicorn-magic": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", @@ -2842,136 +1705,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/foreground-child": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", - "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", - "dev": true, - "license": "ISC", - "dependencies": { - "cross-spawn": "^7.0.6", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true, - "license": "MIT" - }, - "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-east-asian-width": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz", - "integrity": "sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/github-from-package": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", - "dev": true, - "license": "MIT" - }, - "node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", - "dev": true, - "license": "ISC", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/globby": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-14.1.0.tgz", - "integrity": "sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sindresorhus/merge-streams": "^2.1.0", - "fast-glob": "^3.3.3", - "ignore": "^7.0.3", - "path-type": "^6.0.0", - "slash": "^5.1.0", - "unicorn-magic": "^0.3.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/https-proxy-agent": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -2985,230 +1718,13 @@ "node": ">=0.10.0" } }, - "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": "7.0.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", - "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/ignore-by-default": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-2.1.0.tgz", - "integrity": "sha512-yiWd4GVmJp0Q6ghmM2B/V3oZGRmjrKLXvHR3TE1nfoXsmoggllfZUQe74EN0fJdPFZu2NIvNdrMMLm3OsV7Ohw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10 <11 || >=12 <13 || >=14" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/indent-string": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", - "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true, - "license": "ISC" - }, - "node_modules/irregular-plurals": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-3.5.0.tgz", - "integrity": "sha512-1ANGLZ+Nkv1ptFb2pa8oG8Lem4krflKuX/gINiHJHjJUKaJHk/SXk5x6K3J+39/p0h1RQ2saROclJJ+QLvETCQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", - "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-promise": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", - "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "node_modules/js-tokens": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", + "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", "dev": true, "license": "MIT" }, - "node_modules/is-unicode-supported": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", - "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, - "license": "ISC" - }, - "node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, - "node_modules/js-string-escape": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz", - "integrity": "sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/load-json-file": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-7.0.1.tgz", - "integrity": "sha512-Gnxj3ev3mB5TkVBGad0JM6dmLiQL+o0t23JPBZ9sd+yvSLk05mFoqKBw5N8gbbkU4TNXyqCgIrl/VM17OgUIgQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/locate-path": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", @@ -3225,206 +1741,42 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "node_modules/loupe": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", + "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", "dev": true, "license": "MIT" }, - "node_modules/lodash-es": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", - "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", - "dev": true, - "license": "MIT" - }, - "node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/matcher": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/matcher/-/matcher-5.0.0.tgz", - "integrity": "sha512-s2EMBOWtXFc8dgqvoAzKJXxNHibcdJMV0gwqKUaw9E2JBJuGUK7DrNKrA6g/i+v72TT16+6sVm5mS3thaMLQUw==", - "dev": true, - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^5.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/md5-hex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-3.0.1.tgz", - "integrity": "sha512-BUiRtTtV39LIJwinWBjqVsU9xhdnz7/i889V859IBFpuqGAj6LuOvHv5XLbgZ2R7ptJoJaEcxkv88/h25T7Ciw==", - "dev": true, - "license": "MIT", - "dependencies": { - "blueimp-md5": "^2.10.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/memoize": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/memoize/-/memoize-10.1.0.tgz", - "integrity": "sha512-MMbFhJzh4Jlg/poq1si90XRlTZRDHVqdlz2mPyGJ6kqMpyHUyVpDd5gpFAvVehW64+RA1eKE9Yt8aSLY7w2Kgg==", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-function": "^5.0.1" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sindresorhus/memoize?sponsor=1" - } - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "dev": true, - "license": "MIT", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/micromatch/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/mimic-function": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", - "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/minizlib": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.2.tgz", - "integrity": "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==", - "dev": true, - "license": "MIT", - "dependencies": { - "minipass": "^7.1.2" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/mkdirp": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", - "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "node_modules/lz-string": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", "dev": true, "license": "MIT", "bin": { - "mkdirp": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "lz-string": "bin/bin.js" } }, - "node_modules/mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "node_modules/magic-string": { + "version": "0.30.18", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.18.tgz", + "integrity": "sha512-yi8swmWbO17qHhwIBNeeZxTceJMeBvWJaId6dyvTSOwTipqeHhMhOrz6513r1sOKnpvQ7zkhlG8tPrpilwTxHQ==", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/mrmime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", + "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } }, "node_modules/ms": { "version": "2.1.3", @@ -3443,93 +1795,23 @@ "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/napi-build-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz", - "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==", + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", "dev": true, - "license": "MIT" - }, - "node_modules/node-abi": { - "version": "3.75.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.75.0.tgz", - "integrity": "sha512-OhYaY5sDsIka7H7AtijtI9jwGYLyl29eQn/W623DiN/MIv5sUqc4g7BIDThX+gb7di9f6xK02nkp8sdfFWZLTg==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "dev": true, - "license": "MIT", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" } - } - }, - "node_modules/node-gyp-build": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", - "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", - "dev": true, + ], "license": "MIT", "bin": { - "node-gyp-build": "bin.js", - "node-gyp-build-optional": "optional.js", - "node-gyp-build-test": "build-test.js" - } - }, - "node_modules/nofilter": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-3.1.0.tgz", - "integrity": "sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.19" - } - }, - "node_modules/nopt": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-8.1.0.tgz", - "integrity": "sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==", - "dev": true, - "license": "ISC", - "dependencies": { - "abbrev": "^3.0.0" - }, - "bin": { - "nopt": "bin/nopt.js" + "nanoid": "bin/nanoid.cjs" }, "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "license": "ISC", - "dependencies": { - "wrappy": "1" + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, "node_modules/os-tmpdir": { @@ -3574,56 +1856,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-map": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.3.tgz", - "integrity": "sha512-VkndIv2fIB99swvQoA65bm+fsmt6UNdGeIB0oxBs+WhAhdh08QA04JXpI7rbB9r08/nkbysKoya9rtDERYOYMA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/package-config": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/package-config/-/package-config-5.0.0.tgz", - "integrity": "sha512-GYTTew2slBcYdvRHqjhwaaydVMvn/qrGC323+nKclYioNSLTDUM/lGgtGTgyHVtYcozb+XkE8CNhwcraOmZ9Mg==", - "dev": true, - "license": "MIT", - "dependencies": { - "find-up-simple": "^1.0.0", - "load-json-file": "^7.0.1" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/package-json-from-dist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", - "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", - "dev": true, - "license": "BlueOak-1.0.0" - }, - "node_modules/parse-ms": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz", - "integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/path-exists": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", @@ -3634,45 +1866,29 @@ "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/pathval": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", + "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", "dev": true, "license": "MIT", "engines": { - "node": ">=8" + "node": ">= 14.16" } }, - "node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "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": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/path-type": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-6.0.0.tgz", - "integrity": "sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "license": "ISC" }, "node_modules/picomatch": { "version": "4.0.3", @@ -3687,217 +1903,130 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/plur": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/plur/-/plur-5.1.0.tgz", - "integrity": "sha512-VP/72JeXqak2KiOzjgKtQen5y3IZHn+9GOuLDafPv0eXa47xq0At93XahYBs26MsifCQ4enGKwbjBTKgb9QJXg==", + "node_modules/playwright": { + "version": "1.55.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.55.0.tgz", + "integrity": "sha512-sdCWStblvV1YU909Xqx0DhOjPZE4/5lJsIS84IfN9dAZfcl/CIZ5O8l3o0j7hPMjDvqoTF8ZUcc+i/GL5erstA==", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "irregular-plurals": "^3.3.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/prebuild-install": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", - "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==", - "dev": true, - "license": "MIT", - "dependencies": { - "detect-libc": "^2.0.0", - "expand-template": "^2.0.3", - "github-from-package": "0.0.0", - "minimist": "^1.2.3", - "mkdirp-classic": "^0.5.3", - "napi-build-utils": "^2.0.0", - "node-abi": "^3.3.0", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^4.0.0", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0" + "playwright-core": "1.55.0" }, "bin": { - "prebuild-install": "bin.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/pretty-ms": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.2.0.tgz", - "integrity": "sha512-4yf0QO/sllf/1zbZWYnvWw3NxCQwLXKzIj0G849LSufP15BXKM0rbD2Z3wVnkMfjdn/CB0Dpp444gYAACdsplg==", - "dev": true, - "license": "MIT", - "dependencies": { - "parse-ms": "^4.0.0" + "playwright": "cli.js" }, "engines": { "node": ">=18" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "optionalDependencies": { + "fsevents": "2.3.2" } }, - "node_modules/pump": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", - "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", + "node_modules/playwright-core": { + "version": "1.55.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.55.0.tgz", + "integrity": "sha512-GvZs4vU3U5ro2nZpeiwyb0zuFaqb9sUiAJuyrWpcGouD8y9/HLgGbNRjIph7zU9D3hnPaisMl9zG9CgFi/biIg==", "dev": true, - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" } }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", "dev": true, "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, { "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" + "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true, "license": "MIT" }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "node_modules/rollup": { + "version": "4.50.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.50.1.tgz", + "integrity": "sha512-78E9voJHwnXQMiQdiqswVLZwJIzdBKJ1GdI5Zx6XwoFKUIk09/sSrr+05QFzvYb8q6Y9pPV45zzDuYa3907TZA==", "dev": true, - "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "license": "MIT", "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" + "@types/estree": "1.0.8" }, "bin": { - "rc": "cli.js" - } - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "rollup": "dist/bin/rollup" }, "engines": { - "node": ">= 6" - } - }, - "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/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "resolve-from": "^5.0.0" + "node": ">=18.0.0", + "npm": ">=8.0.0" }, - "engines": { - "node": ">=8" + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.50.1", + "@rollup/rollup-android-arm64": "4.50.1", + "@rollup/rollup-darwin-arm64": "4.50.1", + "@rollup/rollup-darwin-x64": "4.50.1", + "@rollup/rollup-freebsd-arm64": "4.50.1", + "@rollup/rollup-freebsd-x64": "4.50.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.50.1", + "@rollup/rollup-linux-arm-musleabihf": "4.50.1", + "@rollup/rollup-linux-arm64-gnu": "4.50.1", + "@rollup/rollup-linux-arm64-musl": "4.50.1", + "@rollup/rollup-linux-loongarch64-gnu": "4.50.1", + "@rollup/rollup-linux-ppc64-gnu": "4.50.1", + "@rollup/rollup-linux-riscv64-gnu": "4.50.1", + "@rollup/rollup-linux-riscv64-musl": "4.50.1", + "@rollup/rollup-linux-s390x-gnu": "4.50.1", + "@rollup/rollup-linux-x64-gnu": "4.50.1", + "@rollup/rollup-linux-x64-musl": "4.50.1", + "@rollup/rollup-openharmony-arm64": "4.50.1", + "@rollup/rollup-win32-arm64-msvc": "4.50.1", + "@rollup/rollup-win32-ia32-msvc": "4.50.1", + "@rollup/rollup-win32-x64-msvc": "4.50.1", + "fsevents": "~2.3.2" } }, - "node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/reusify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", - "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", - "dev": true, - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "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": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "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/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -3918,44 +2047,12 @@ "node": ">=10" } }, - "node_modules/serialize-error": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", - "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^0.13.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/shebang-command": { + "node_modules/siginfo": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", "dev": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } + "license": "ISC" }, "node_modules/signal-exit": { "version": "4.1.0", @@ -3970,336 +2067,117 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "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/simple-get": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", - "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", - "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": { - "decompress-response": "^6.0.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, - "node_modules/slash": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", - "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/slice-ansi": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", - "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "node_modules/sirv": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.2.tgz", + "integrity": "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==", "dev": true, "license": "MIT", "dependencies": { - "ansi-styles": "^6.0.0", - "is-fullwidth-code-point": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/stack-utils": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", - "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/stack-utils/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-width": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", - "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^10.3.0", - "get-east-asian-width": "^1.0.0", - "strip-ansi": "^7.1.0" + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" }, "engines": { "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/string-width-cjs": { - "name": "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==", + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "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-width-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/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/string-width-cjs/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==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "dev": true, - "license": "MIT", + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, - "node_modules/supertap": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/supertap/-/supertap-3.0.1.tgz", - "integrity": "sha512-u1ZpIBCawJnO+0QePsEiOknOfCRq0yERxiAchT0i4li0WHNUJbf0evXXSXOcCAR4M8iMDoajXYmstm/qO81Isw==", + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", "dev": true, - "license": "MIT", - "dependencies": { - "indent-string": "^5.0.0", - "js-yaml": "^3.14.1", - "serialize-error": "^7.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } + "license": "MIT" }, - "node_modules/tar": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", - "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", + "node_modules/std-env": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.9.0.tgz", + "integrity": "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==", "dev": true, - "license": "ISC", - "dependencies": { - "@isaacs/fs-minipass": "^4.0.0", - "chownr": "^3.0.0", - "minipass": "^7.1.2", - "minizlib": "^3.0.1", - "mkdirp": "^3.0.1", - "yallist": "^5.0.0" - }, - "engines": { - "node": ">=18" - } + "license": "MIT" }, - "node_modules/tar-fs": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.3.tgz", - "integrity": "sha512-090nwYJDmlhwFwEW3QQl+vaNnxsO2yVsd45eTKRBzSzu+hlb1w2K9inVq5b0ngXuLVqQ4ApvsUHHnu/zQNkWAg==", - "dev": true, - "license": "MIT", - "dependencies": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.1.4" - } - }, - "node_modules/tar-fs/node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true, - "license": "ISC" - }, - "node_modules/tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/temp-dir": { + "node_modules/strip-literal": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-3.0.0.tgz", - "integrity": "sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.0.0.tgz", + "integrity": "sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==", "dev": true, "license": "MIT", - "engines": { - "node": ">=14.16" + "dependencies": { + "js-tokens": "^9.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" } }, - "node_modules/time-zone": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/time-zone/-/time-zone-1.0.0.tgz", - "integrity": "sha512-TIsDdtKo6+XrPtiTm1ssmMngN1sAhyKnTO2kunQWqNPWIVvCm15Wmw4SWInwTVgJ5u/Tr04+8Ei9TNcw4x4ONA==", + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinypool": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", + "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", "dev": true, "license": "MIT", "engines": { - "node": ">=4" + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/tinyrainbow": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", + "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.3.tgz", + "integrity": "sha512-t2T/WLB2WRgZ9EpE4jgPJ9w+i66UZfDc8wHh0xrwiRNN+UwH98GIJkTeZqX9rg0i0ptwzqW+uYeIF0T4F8LR7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" } }, "node_modules/tmp": { @@ -4315,46 +2193,22 @@ "node": ">=0.6.0" } }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "node_modules/totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", "dev": true, "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, "engines": { - "node": ">=8.0" + "node": ">=6" } }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true, - "license": "MIT" - }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "dev": true, "license": "0BSD" }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, "node_modules/typanion": { "version": "3.14.0", "resolved": "https://registry.npmjs.org/typanion/-/typanion-3.14.0.tgz", @@ -4365,19 +2219,6 @@ "website" ] }, - "node_modules/type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/typescript": { "version": "5.9.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", @@ -4392,18 +2233,12 @@ "node": ">=14.17" } }, - "node_modules/unicorn-magic": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", - "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", + "node_modules/undici-types": { + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.10.0.tgz", + "integrity": "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "license": "MIT" }, "node_modules/universal-user-agent": { "version": "7.0.3", @@ -4412,313 +2247,214 @@ "dev": true, "license": "ISC" }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true, - "license": "MIT" - }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "dev": true, - "license": "BSD-2-Clause" - }, - "node_modules/well-known-symbols": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/well-known-symbols/-/well-known-symbols-2.0.0.tgz", - "integrity": "sha512-ZMjC3ho+KXo0BfJb7JgtQ5IBuvnShdlACNkKkdsqBmYw3bPAaJfPeYUo6tLUaT5tG/Gkh7xkpBhKRQ9e7pyg9Q==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=6" - } - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "node_modules/vite": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.5.tgz", + "integrity": "sha512-4cKBO9wR75r0BeIWWWId9XK9Lj6La5X846Zw9dFfzMRw38IlTk2iCcUt6hsyiDRcPidc55ZParFYDXi0nXOeLQ==", "dev": true, "license": "MIT", "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" + "esbuild": "^0.25.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" }, "bin": { - "node-which": "bin/node-which" + "vite": "bin/vite.js" }, "engines": { - "node": ">= 8" - } - }, - "node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" + "node": "^20.19.0 || >=22.12.0" }, "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } } }, - "node_modules/wrap-ansi-cjs": { - "name": "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/vite-node": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz", + "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==", "dev": true, "license": "MIT", "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "cac": "^6.7.14", + "debug": "^4.4.1", + "es-module-lexer": "^1.7.0", + "pathe": "^2.0.3", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + }, + "bin": { + "vite-node": "vite-node.mjs" }, "engines": { - "node": ">=10" + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" }, "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "url": "https://opencollective.com/vitest" } }, - "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/vitest": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.4.tgz", + "integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==", "dev": true, "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "@types/chai": "^5.2.2", + "@vitest/expect": "3.2.4", + "@vitest/mocker": "3.2.4", + "@vitest/pretty-format": "^3.2.4", + "@vitest/runner": "3.2.4", + "@vitest/snapshot": "3.2.4", + "@vitest/spy": "3.2.4", + "@vitest/utils": "3.2.4", + "chai": "^5.2.0", + "debug": "^4.4.1", + "expect-type": "^1.2.1", + "magic-string": "^0.30.17", + "pathe": "^2.0.3", + "picomatch": "^4.0.2", + "std-env": "^3.9.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.2", + "tinyglobby": "^0.2.14", + "tinypool": "^1.1.1", + "tinyrainbow": "^2.0.0", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", + "vite-node": "3.2.4", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" }, "engines": { - "node": ">=8" + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/debug": "^4.1.12", + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "@vitest/browser": "3.2.4", + "@vitest/ui": "3.2.4", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/debug": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } } }, - "node_modules/wrap-ansi-cjs/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/wrap-ansi-cjs/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==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi-cjs/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==", + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", "dev": true, "license": "MIT", "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" }, "engines": { "node": ">=8" } }, - "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true, - "license": "MIT" - }, - "node_modules/wrap-ansi/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/write-file-atomic": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-6.0.0.tgz", - "integrity": "sha512-GmqrO8WJ1NuzJ2DrziEI2o57jKAVIQNf8a18W3nCYU3H7PNWqCCVTeH6/NQE93CIllIgQS98rrmVkYgTX9fFJQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": "^18.17.0 || >=20.5.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/yallist": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", - "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", - "dev": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - }, - "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/yargs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "node_modules/ws": { + "version": "8.18.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", "dev": true, "license": "MIT", "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/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/yargs/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==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/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" + "node": ">=10.0.0" }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" }, - "engines": { - "node": ">=8" + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } } }, "node_modules/yocto-queue": { @@ -4746,6 +2482,53 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "packages/browser": { + "name": "@tursodatabase/database-browser", + "version": "0.1.5-pre.5", + "license": "MIT", + "dependencies": { + "@napi-rs/wasm-runtime": "^1.0.3", + "@tursodatabase/database-common": "^0.1.5-pre.5" + }, + "devDependencies": { + "@napi-rs/cli": "^3.1.5", + "@vitest/browser": "^3.2.4", + "playwright": "^1.55.0", + "typescript": "^5.9.2", + "vitest": "^3.2.4" + } + }, + "packages/common": { + "name": "@tursodatabase/database-common", + "version": "0.1.5-pre.5", + "license": "MIT", + "devDependencies": { + "typescript": "^5.9.2" + } + }, + "packages/core": { + "name": "@tursodatabase/database-core", + "version": "0.1.5-pre.3", + "extraneous": true, + "license": "MIT", + "devDependencies": { + "typescript": "^5.9.2" + } + }, + "packages/native": { + "name": "@tursodatabase/database", + "version": "0.1.5-pre.5", + "license": "MIT", + "dependencies": { + "@tursodatabase/database-common": "^0.1.5-pre.5" + }, + "devDependencies": { + "@napi-rs/cli": "^3.1.5", + "@types/node": "^24.3.1", + "typescript": "^5.9.2", + "vitest": "^3.2.4" + } } } -} \ No newline at end of file +} diff --git a/bindings/javascript/package.browser.json b/bindings/javascript/package.browser.json deleted file mode 100644 index 0242ed5ad..000000000 --- a/bindings/javascript/package.browser.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "name": "@tursodatabase/database-browser", - "version": "0.1.5-pre.2", - "repository": { - "type": "git", - "url": "https://github.com/tursodatabase/turso" - }, - "description": "The Turso database library specifically for browser/web environment", - "module": "./dist/promise.js", - "main": "./dist/promise.js", - "type": "module", - "exports": { - ".": "./dist/promise.js", - "./compat": "./dist/compat.js" - }, - "files": [ - "browser.js", - "index.js", - "index.d.ts", - "dist/**" - ], - "types": "index.d.ts", - "napi": { - "binaryName": "turso", - "targets": [ - "wasm32-wasip1-threads" - ] - }, - "license": "MIT", - "devDependencies": { - "@napi-rs/cli": "^3.0.4", - "@napi-rs/wasm-runtime": "^1.0.1", - "ava": "^6.0.1", - "better-sqlite3": "^11.9.1", - "typescript": "^5.9.2" - }, - "ava": { - "timeout": "3m" - }, - "engines": { - "node": ">= 10" - }, - "scripts": { - "artifacts": "napi artifacts", - "build": "npm exec tsc && napi build --platform --release --esm", - "build:debug": "npm exec tsc && napi build --platform", - "prepublishOnly": "npm exec tsc && napi prepublish -t npm --skip-optional-publish", - "test": "true", - "universal": "napi universalize", - "version": "napi version" - }, - "packageManager": "yarn@4.9.2", - "imports": { - "#entry-point": { - "types": "./index.d.ts", - "browser": "./browser.js" - } - } -} diff --git a/bindings/javascript/package.json b/bindings/javascript/package.json index 894f7e551..70213de55 100644 --- a/bindings/javascript/package.json +++ b/bindings/javascript/package.json @@ -1,64 +1,13 @@ { - "name": "@tursodatabase/database", - "version": "0.1.5-pre.3", - "repository": { - "type": "git", - "url": "https://github.com/tursodatabase/turso" - }, - "description": "The Turso database library", - "module": "./dist/promise.js", - "main": "./dist/promise.js", - "type": "module", - "exports": { - ".": "./dist/promise.js", - "./compat": "./dist/compat.js" - }, - "files": [ - "browser.js", - "index.js", - "index.d.ts", - "dist/**" - ], - "types": "index.d.ts", - "napi": { - "binaryName": "turso", - "targets": [ - "x86_64-unknown-linux-gnu", - "x86_64-pc-windows-msvc", - "universal-apple-darwin", - "aarch64-unknown-linux-gnu", - "wasm32-wasip1-threads" - ] - }, - "license": "MIT", - "devDependencies": { - "@napi-rs/cli": "^3.0.4", - "@napi-rs/wasm-runtime": "^1.0.1", - "ava": "^6.0.1", - "better-sqlite3": "^11.9.1", - "typescript": "^5.9.2" - }, - "ava": { - "timeout": "3m" - }, - "engines": { - "node": ">= 10" - }, "scripts": { - "artifacts": "napi artifacts", - "build": "npm exec tsc && napi build --platform --release --esm", - "build:debug": "npm exec tsc && napi build --platform", - "prepublishOnly": "npm exec tsc && napi prepublish -t npm", - "test": "true", - "universal": "napi universalize", - "version": "napi version" + "build": "npm run build --workspaces", + "tsc-build": "npm run tsc-build --workspaces", + "test": "npm run test --workspaces" }, - "packageManager": "yarn@4.9.2", - "imports": { - "#entry-point": { - "types": "./index.d.ts", - "browser": "./browser.js", - "node": "./index.js" - } - } -} \ No newline at end of file + "workspaces": [ + "packages/common", + "packages/native", + "packages/browser" + ], + "version": "0.1.5-pre.5" +} diff --git a/bindings/javascript/packages/browser/README.md b/bindings/javascript/packages/browser/README.md new file mode 100644 index 000000000..e443f495e --- /dev/null +++ b/bindings/javascript/packages/browser/README.md @@ -0,0 +1,124 @@ +

+

Turso Database for JavaScript in Browser

+

+ +

+ npm + +

+

+ Chat with other users of Turso on Discord +

+ +--- + +## About + +This package is the Turso embedded database library for JavaScript in Browser. + +> **⚠️ Warning:** This software is ALPHA, only use for development, testing, and experimentation. We are working to make it production ready, but do not use it for critical data right now. + +## Features + +- **SQLite compatible:** SQLite query language and file format support ([status](https://github.com/tursodatabase/turso/blob/main/COMPAT.md)). +- **In-process**: No network overhead, runs directly in your Node.js process +- **TypeScript support**: Full TypeScript definitions included + +## Installation + +```bash +npm install @tursodatabase/database-browser +``` + +## Getting Started + +### In-Memory Database + +```javascript +import { connect } from '@tursodatabase/database-browser'; + +// Create an in-memory database +const db = await connect(':memory:'); + +// Create a table +await db.exec('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, email TEXT)'); + +// Insert data +const insert = db.prepare('INSERT INTO users (name, email) VALUES (?, ?)'); +await insert.run('Alice', 'alice@example.com'); +await insert.run('Bob', 'bob@example.com'); + +// Query data +const users = await db.prepare('SELECT * FROM users').all(); +console.log(users); +// Output: [ +// { id: 1, name: 'Alice', email: 'alice@example.com' }, +// { id: 2, name: 'Bob', email: 'bob@example.com' } +// ] +``` + +### File-Based Database + +```javascript +import { connect } from '@tursodatabase/database-browser'; + +// Create or open a database file +const db = await connect('my-database.db'); + +// Create a table +await db.exec(` + CREATE TABLE IF NOT EXISTS posts ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + title TEXT NOT NULL, + content TEXT, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP + ) +`); + +// Insert a post +const insertPost = db.prepare('INSERT INTO posts (title, content) VALUES (?, ?)'); +const result = await insertPost.run('Hello World', 'This is my first blog post!'); + +console.log(`Inserted post with ID: ${result.lastInsertRowid}`); +``` + +### Transactions + +```javascript +import { connect } from '@tursodatabase/database-browser'; + +const db = await connect('transactions.db'); + +// Using transactions for atomic operations +const transaction = db.transaction(async (users) => { + const insert = db.prepare('INSERT INTO users (name, email) VALUES (?, ?)'); + for (const user of users) { + await insert.run(user.name, user.email); + } +}); + +// Execute transaction +await transaction([ + { name: 'Alice', email: 'alice@example.com' }, + { name: 'Bob', email: 'bob@example.com' } +]); +``` + +## API Reference + +For complete API documentation, see [JavaScript API Reference](../../../../docs/javascript-api-reference.md). + +## Related Packages + +* The [@tursodatabase/serverless](https://www.npmjs.com/package/@tursodatabase/serverless) package provides a serverless driver with the same API. +* The [@tursodatabase/sync](https://www.npmjs.com/package/@tursodatabase/sync) package provides bidirectional sync between a local Turso database and Turso Cloud. + +## License + +This project is licensed under the [MIT license](../../LICENSE.md). + +## Support + +- [GitHub Issues](https://github.com/tursodatabase/turso/issues) +- [Documentation](https://docs.turso.tech) +- [Discord Community](https://tur.so/discord) diff --git a/bindings/javascript/turso.wasi-browser.js b/bindings/javascript/packages/browser/index.js similarity index 60% rename from bindings/javascript/turso.wasi-browser.js rename to bindings/javascript/packages/browser/index.js index b17db8b4d..be8564969 100644 --- a/bindings/javascript/turso.wasi-browser.js +++ b/bindings/javascript/packages/browser/index.js @@ -1,7 +1,7 @@ import { createOnMessage as __wasmCreateOnMessageForFsProxy, getDefaultContext as __emnapiGetDefaultContext, - instantiateNapiModuleSync as __emnapiInstantiateNapiModuleSync, + instantiateNapiModule as __emnapiInstantiateNapiModule, WASI as __WASI, } from '@napi-rs/wasm-runtime' @@ -23,19 +23,25 @@ const __sharedMemory = new WebAssembly.Memory({ const __wasmFile = await fetch(__wasmUrl).then((res) => res.arrayBuffer()) +export let MainWorker = null; + +function panic(name) { + throw new Error(`method ${name} must be invoked only from the main thread`); +} + const { instance: __napiInstance, module: __wasiModule, napiModule: __napiModule, -} = __emnapiInstantiateNapiModuleSync(__wasmFile, { +} = await __emnapiInstantiateNapiModule(__wasmFile, { context: __emnapiContext, - asyncWorkPoolSize: 4, + asyncWorkPoolSize: 1, wasi: __wasi, onCreateWorker() { - const worker = new Worker(new URL('./wasi-worker-browser.mjs', import.meta.url), { + const worker = new Worker(new URL('./worker.mjs', import.meta.url), { type: 'module', }) - + MainWorker = worker; return worker }, overwriteImports(importObject) { @@ -44,6 +50,13 @@ const { ...importObject.napi, ...importObject.emnapi, memory: __sharedMemory, + is_web_worker: () => false, + lookup_file: () => panic("lookup_file"), + read: () => panic("read"), + write: () => panic("write"), + sync: () => panic("sync"), + truncate: () => panic("truncate"), + size: () => panic("size"), } return importObject }, @@ -57,4 +70,8 @@ const { }) export default __napiModule.exports export const Database = __napiModule.exports.Database +export const Opfs = __napiModule.exports.Opfs +export const OpfsFile = __napiModule.exports.OpfsFile export const Statement = __napiModule.exports.Statement +export const connect = __napiModule.exports.connect +export const initThreadPool = __napiModule.exports.initThreadPool diff --git a/bindings/javascript/packages/browser/package.json b/bindings/javascript/packages/browser/package.json new file mode 100644 index 000000000..5475fd25b --- /dev/null +++ b/bindings/javascript/packages/browser/package.json @@ -0,0 +1,45 @@ +{ + "name": "@tursodatabase/database-browser", + "version": "0.1.5-pre.5", + "repository": { + "type": "git", + "url": "https://github.com/tursodatabase/turso" + }, + "type": "module", + "license": "MIT", + "main": "dist/promise.js", + "packageManager": "yarn@4.9.2", + "files": [ + "index.js", + "worker.mjs", + "turso.wasm32-wasi.wasm", + "dist/**", + "README.md" + ], + "devDependencies": { + "@napi-rs/cli": "^3.1.5", + "@vitest/browser": "^3.2.4", + "playwright": "^1.55.0", + "typescript": "^5.9.2", + "vitest": "^3.2.4" + }, + "scripts": { + "napi-build": "napi build --features browser --release --platform --target wasm32-wasip1-threads --no-js --manifest-path ../../Cargo.toml --output-dir . && rm index.d.ts turso.wasi* wasi* browser.js", + "tsc-build": "npm exec tsc", + "build": "npm run napi-build && npm run tsc-build", + "test": "CI=1 vitest --browser=chromium --run && CI=1 vitest --browser=firefox --run" + }, + "napi": { + "binaryName": "turso", + "targets": [ + "wasm32-wasip1-threads" + ] + }, + "imports": { + "#index": "./index.js" + }, + "dependencies": { + "@napi-rs/wasm-runtime": "^1.0.3", + "@tursodatabase/database-common": "^0.1.5-pre.5" + } +} diff --git a/bindings/javascript/packages/browser/promise.test.ts b/bindings/javascript/packages/browser/promise.test.ts new file mode 100644 index 000000000..87bd130be --- /dev/null +++ b/bindings/javascript/packages/browser/promise.test.ts @@ -0,0 +1,95 @@ +import { expect, test, afterEach } from 'vitest' +import { connect } from './promise.js' + +test('in-memory db', async () => { + const db = await connect(":memory:"); + await db.exec("CREATE TABLE t(x)"); + await db.exec("INSERT INTO t VALUES (1), (2), (3)"); + const stmt = db.prepare("SELECT * FROM t WHERE x % 2 = ?"); + const rows = await stmt.all([1]); + expect(rows).toEqual([{ x: 1 }, { x: 3 }]); +}) + +test('on-disk db', async () => { + const path = `test-${(Math.random() * 10000) | 0}.db`; + const db1 = await connect(path); + await db1.exec("CREATE TABLE t(x)"); + await db1.exec("INSERT INTO t VALUES (1), (2), (3)"); + const stmt1 = db1.prepare("SELECT * FROM t WHERE x % 2 = ?"); + expect(stmt1.columns()).toEqual([{ name: "x", column: null, database: null, table: null, type: null }]); + const rows1 = await stmt1.all([1]); + expect(rows1).toEqual([{ x: 1 }, { x: 3 }]); + await db1.close(); + stmt1.close(); + + const db2 = await connect(path); + const stmt2 = db2.prepare("SELECT * FROM t WHERE x % 2 = ?"); + expect(stmt2.columns()).toEqual([{ name: "x", column: null, database: null, table: null, type: null }]); + const rows2 = await stmt2.all([1]); + expect(rows2).toEqual([{ x: 1 }, { x: 3 }]); + db2.close(); +}) + +test('attach', async () => { + const path1 = `test-${(Math.random() * 10000) | 0}.db`; + const path2 = `test-${(Math.random() * 10000) | 0}.db`; + const db1 = await connect(path1); + await db1.exec("CREATE TABLE t(x)"); + await db1.exec("INSERT INTO t VALUES (1), (2), (3)"); + const db2 = await connect(path2); + await db2.exec("CREATE TABLE q(x)"); + await db2.exec("INSERT INTO q VALUES (4), (5), (6)"); + + await db1.exec(`ATTACH '${path2}' as secondary`); + + const stmt = db1.prepare("SELECT * FROM t UNION ALL SELECT * FROM secondary.q"); + expect(stmt.columns()).toEqual([{ name: "x", column: null, database: null, table: null, type: null }]); + const rows = await stmt.all([1]); + expect(rows).toEqual([{ x: 1 }, { x: 2 }, { x: 3 }, { x: 4 }, { x: 5 }, { x: 6 }]); +}) + +test('blobs', async () => { + const db = await connect(":memory:"); + const rows = await db.prepare("SELECT x'1020' as x").all(); + expect(rows).toEqual([{ x: new Uint8Array([16, 32]) }]) +}) + + +test('example-1', async () => { + const db = await connect(':memory:'); + await db.exec('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, email TEXT)'); + + const insert = db.prepare('INSERT INTO users (name, email) VALUES (?, ?)'); + await insert.run('Alice', 'alice@example.com'); + await insert.run('Bob', 'bob@example.com'); + + const users = await db.prepare('SELECT * FROM users').all(); + expect(users).toEqual([ + { id: 1, name: 'Alice', email: 'alice@example.com' }, + { id: 2, name: 'Bob', email: 'bob@example.com' } + ]); +}) + +test('example-2', async () => { + const db = await connect(':memory:'); + await db.exec('CREATE TABLE users (name, email)'); + // Using transactions for atomic operations + const transaction = db.transaction(async (users) => { + const insert = db.prepare('INSERT INTO users (name, email) VALUES (?, ?)'); + for (const user of users) { + await insert.run(user.name, user.email); + } + }); + + // Execute transaction + await transaction([ + { name: 'Alice', email: 'alice@example.com' }, + { name: 'Bob', email: 'bob@example.com' } + ]); + + const rows = await db.prepare('SELECT * FROM users').all(); + expect(rows).toEqual([ + { name: 'Alice', email: 'alice@example.com' }, + { name: 'Bob', email: 'bob@example.com' } + ]); +}) \ No newline at end of file diff --git a/bindings/javascript/packages/browser/promise.ts b/bindings/javascript/packages/browser/promise.ts new file mode 100644 index 000000000..8f713f958 --- /dev/null +++ b/bindings/javascript/packages/browser/promise.ts @@ -0,0 +1,78 @@ +import { DatabasePromise, NativeDatabase, DatabaseOpts, SqliteError } from "@tursodatabase/database-common" +import { connect as nativeConnect, initThreadPool, MainWorker } from "#index"; + +let workerRequestId = 0; +class Database extends DatabasePromise { + files: string[]; + constructor(db: NativeDatabase, files: string[], opts: DatabaseOpts = {}) { + super(db, opts) + this.files = files; + } + async close() { + let currentId = workerRequestId; + workerRequestId += this.files.length; + + let tasks = []; + for (const file of this.files) { + (MainWorker as any).postMessage({ __turso__: "unregister", path: file, id: currentId }); + tasks.push(waitFor(currentId)); + currentId += 1; + } + await Promise.all(tasks); + this.db.close(); + } +} + +function waitFor(id: number): Promise { + let waitResolve, waitReject; + const callback = msg => { + if (msg.data.id == id) { + if (msg.data.error != null) { + waitReject(msg.data.error) + } else { + waitResolve() + } + cleanup(); + } + }; + const cleanup = () => (MainWorker as any).removeEventListener("message", callback); + + (MainWorker as any).addEventListener("message", callback); + const result = new Promise((resolve, reject) => { + waitResolve = resolve; + waitReject = reject; + }); + return result; +} + +/** + * Creates a new database connection asynchronously. + * + * @param {string} path - Path to the database file. + * @param {Object} opts - Options for database behavior. + * @returns {Promise} - A promise that resolves to a Database instance. + */ +async function connect(path: string, opts: DatabaseOpts = {}): Promise { + if (path == ":memory:") { + const db = await nativeConnect(path, { tracing: opts.tracing }); + return new Database(db, [], opts); + } + await initThreadPool(); + if (MainWorker == null) { + throw new Error("panic: MainWorker is not set"); + } + + let currentId = workerRequestId; + workerRequestId += 2; + + let dbHandlePromise = waitFor(currentId); + let walHandlePromise = waitFor(currentId + 1); + (MainWorker as any).postMessage({ __turso__: "register", path: `${path}`, id: currentId }); + (MainWorker as any).postMessage({ __turso__: "register", path: `${path}-wal`, id: currentId + 1 }); + await Promise.all([dbHandlePromise, walHandlePromise]); + const db = await nativeConnect(path, { tracing: opts.tracing }); + const files = [path, `${path}-wal`]; + return new Database(db, files, opts); +} + +export { connect, Database, SqliteError } diff --git a/bindings/javascript/packages/browser/tsconfig.json b/bindings/javascript/packages/browser/tsconfig.json new file mode 100644 index 000000000..b46abc167 --- /dev/null +++ b/bindings/javascript/packages/browser/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "skipLibCheck": true, + "declaration": true, + "declarationMap": true, + "module": "nodenext", + "target": "esnext", + "outDir": "dist/", + "lib": [ + "es2020" + ], + "paths": { + "#index": [ + "./index.js" + ] + } + }, + "include": [ + "*" + ] +} \ No newline at end of file diff --git a/bindings/javascript/packages/browser/vitest.config.ts b/bindings/javascript/packages/browser/vitest.config.ts new file mode 100644 index 000000000..deeaec485 --- /dev/null +++ b/bindings/javascript/packages/browser/vitest.config.ts @@ -0,0 +1,23 @@ +import { defineConfig } from 'vitest/config' + +export default defineConfig({ + define: { + 'process.env.NODE_DEBUG_NATIVE': 'false', + }, + server: { + headers: { + "Cross-Origin-Embedder-Policy": "require-corp", + "Cross-Origin-Opener-Policy": "same-origin" + }, + }, + test: { + browser: { + enabled: true, + provider: 'playwright', + instances: [ + { browser: 'chromium' }, + { browser: 'firefox' } + ], + }, + }, +}) diff --git a/bindings/javascript/packages/browser/worker.mjs b/bindings/javascript/packages/browser/worker.mjs new file mode 100644 index 000000000..9c29d4390 --- /dev/null +++ b/bindings/javascript/packages/browser/worker.mjs @@ -0,0 +1,160 @@ +import { instantiateNapiModuleSync, MessageHandler, WASI } from '@napi-rs/wasm-runtime' + +var fileByPath = new Map(); +var fileByHandle = new Map(); +let fileHandles = 0; +var memory = null; + +function getUint8ArrayFromWasm(ptr, len) { + ptr = ptr >>> 0; + return new Uint8Array(memory.buffer).subarray(ptr, ptr + len); +} + + +async function registerFile(path) { + if (fileByPath.has(path)) { + return; + } + const opfsRoot = await navigator.storage.getDirectory(); + const opfsHandle = await opfsRoot.getFileHandle(path, { create: true }); + const opfsSync = await opfsHandle.createSyncAccessHandle(); + fileHandles += 1; + fileByPath.set(path, { handle: fileHandles, sync: opfsSync }); + fileByHandle.set(fileHandles, opfsSync); +} + +async function unregisterFile(path) { + const file = fileByPath.get(path); + if (file == null) { + return; + } + fileByPath.delete(path); + fileByHandle.delete(file.handle); + file.sync.close(); +} + +function lookup_file(pathPtr, pathLen) { + try { + const buffer = getUint8ArrayFromWasm(pathPtr, pathLen); + const notShared = new Uint8Array(buffer.length); + notShared.set(buffer); + const decoder = new TextDecoder('utf-8'); + const path = decoder.decode(notShared); + const file = fileByPath.get(path); + if (file == null) { + return -404; + } + return file.handle; + } catch (e) { + console.error('lookupFile', pathPtr, pathLen, e); + return -1; + } +} +function read(handle, bufferPtr, bufferLen, offset) { + try { + const buffer = getUint8ArrayFromWasm(bufferPtr, bufferLen); + const file = fileByHandle.get(Number(handle)); + const result = file.read(buffer, { at: Number(offset) }); + return result; + } catch (e) { + console.error('read', handle, bufferPtr, bufferLen, offset, e); + return -1; + } +} +function write(handle, bufferPtr, bufferLen, offset) { + try { + const buffer = getUint8ArrayFromWasm(bufferPtr, bufferLen); + const file = fileByHandle.get(Number(handle)); + const result = file.write(buffer, { at: Number(offset) }); + return result; + } catch (e) { + console.error('write', handle, bufferPtr, bufferLen, offset, e); + return -1; + } +} +function sync(handle) { + try { + const file = fileByHandle.get(Number(handle)); + file.flush(); + return 0; + } catch (e) { + console.error('sync', handle, e); + return -1; + } +} +function truncate(handle, size) { + try { + const file = fileByHandle.get(Number(handle)); + const result = file.truncate(size); + return result; + } catch (e) { + console.error('truncate', handle, size, e); + return -1; + } +} +function size(handle) { + try { + const file = fileByHandle.get(Number(handle)); + const size = file.getSize() + return size; + } catch (e) { + console.error('size', handle, e); + return -1; + } +} + +const handler = new MessageHandler({ + onLoad({ wasmModule, wasmMemory }) { + memory = wasmMemory; + const wasi = new WASI({ + print: function () { + // eslint-disable-next-line no-console + console.log.apply(console, arguments) + }, + printErr: function () { + // eslint-disable-next-line no-console + console.error.apply(console, arguments) + }, + }) + return instantiateNapiModuleSync(wasmModule, { + childThread: true, + wasi, + overwriteImports(importObject) { + importObject.env = { + ...importObject.env, + ...importObject.napi, + ...importObject.emnapi, + memory: wasmMemory, + is_web_worker: () => true, + lookup_file: lookup_file, + read: read, + write: write, + sync: sync, + truncate: truncate, + size: size, + } + }, + }) + }, +}) + +globalThis.onmessage = async function (e) { + if (e.data.__turso__ == 'register') { + try { + await registerFile(e.data.path) + self.postMessage({ id: e.data.id }) + } catch (error) { + self.postMessage({ id: e.data.id, error: error }); + } + return; + } else if (e.data.__turso__ == 'unregister') { + try { + await unregisterFile(e.data.path) + self.postMessage({ id: e.data.id }) + } catch (error) { + self.postMessage({ id: e.data.id, error: error }); + } + return; + } + handler.handle(e) +} diff --git a/bindings/javascript/packages/common/README.md b/bindings/javascript/packages/common/README.md new file mode 100644 index 000000000..179123f7f --- /dev/null +++ b/bindings/javascript/packages/common/README.md @@ -0,0 +1,8 @@ +## About + +This package is the Turso embedded database common JS library which is shared between final builds for Node and Browser. + +Do not use this package directly - instead you must use `@tursodatabase/database` or `@tursodatabase/database-browser`. + +> **⚠️ Warning:** This software is ALPHA, only use for development, testing, and experimentation. We are working to make it production ready, but do not use it for critical data right now. + diff --git a/bindings/javascript/bind.ts b/bindings/javascript/packages/common/bind.ts similarity index 100% rename from bindings/javascript/bind.ts rename to bindings/javascript/packages/common/bind.ts diff --git a/bindings/javascript/compat.ts b/bindings/javascript/packages/common/compat.ts similarity index 94% rename from bindings/javascript/compat.ts rename to bindings/javascript/packages/common/compat.ts index 3b99f0772..d7bd493bb 100644 --- a/bindings/javascript/compat.ts +++ b/bindings/javascript/packages/common/compat.ts @@ -1,12 +1,6 @@ -import { Database as NativeDB, Statement as NativeStatement } from "#entry-point"; import { bindParams } from "./bind.js"; - import { SqliteError } from "./sqlite-error.js"; - -// Step result constants -const STEP_ROW = 1; -const STEP_DONE = 2; -const STEP_IO = 3; +import { NativeDatabase, NativeStatement, STEP_IO, STEP_ROW, STEP_DONE } from "./types.js"; const convertibleErrorTypes = { TypeError }; const CONVERTIBLE_ERROR_PREFIX = "[TURSO_CONVERT_TYPE]"; @@ -35,7 +29,7 @@ function createErrorByName(name, message) { * Database represents a connection that can prepare and execute SQL statements. */ class Database { - db: NativeDB; + db: NativeDatabase; memory: boolean; open: boolean; private _inTransaction: boolean = false; @@ -50,15 +44,14 @@ class Database { * @param {boolean} [opts.fileMustExist=false] - If true, throws if database file does not exist. * @param {number} [opts.timeout=0] - Timeout duration in milliseconds for database operations. Defaults to 0 (no timeout). */ - constructor(path: string, opts: any = {}) { + constructor(db: NativeDatabase, opts: any = {}) { opts.readonly = opts.readonly === undefined ? false : opts.readonly; opts.fileMustExist = opts.fileMustExist === undefined ? false : opts.fileMustExist; opts.timeout = opts.timeout === undefined ? 0 : opts.timeout; - this.db = new NativeDB(path); + this.db = db; this.memory = this.db.memory; - const db = this.db; Object.defineProperties(this, { inTransaction: { @@ -66,7 +59,7 @@ class Database { }, name: { get() { - return path; + return db.path; }, }, readonly: { @@ -199,7 +192,7 @@ class Database { } try { - this.db.batch(sql); + this.db.batchSync(sql); } catch (err) { throw convertError(err); } @@ -301,7 +294,7 @@ class Statement { this.stmt.reset(); bindParams(this.stmt, bindParameters); for (; ;) { - const stepResult = this.stmt.step(); + const stepResult = this.stmt.stepSync(); if (stepResult === STEP_IO) { this.db.db.ioLoopSync(); continue; @@ -330,7 +323,7 @@ class Statement { this.stmt.reset(); bindParams(this.stmt, bindParameters); for (; ;) { - const stepResult = this.stmt.step(); + const stepResult = this.stmt.stepSync(); if (stepResult === STEP_IO) { this.db.db.ioLoopSync(); continue; @@ -354,7 +347,7 @@ class Statement { bindParams(this.stmt, bindParameters); while (true) { - const stepResult = this.stmt.step(); + const stepResult = this.stmt.stepSync(); if (stepResult === STEP_IO) { this.db.db.ioLoopSync(); continue; @@ -378,7 +371,7 @@ class Statement { bindParams(this.stmt, bindParameters); const rows: any[] = []; for (; ;) { - const stepResult = this.stmt.step(); + const stepResult = this.stmt.stepSync(); if (stepResult === STEP_IO) { this.db.db.ioLoopSync(); continue; @@ -417,4 +410,4 @@ class Statement { } } -export { Database, SqliteError } \ No newline at end of file +export { Database, Statement } \ No newline at end of file diff --git a/bindings/javascript/packages/common/index.ts b/bindings/javascript/packages/common/index.ts new file mode 100644 index 000000000..35e092d03 --- /dev/null +++ b/bindings/javascript/packages/common/index.ts @@ -0,0 +1,6 @@ +import { NativeDatabase, NativeStatement, DatabaseOpts } from "./types.js"; +import { Database as DatabaseCompat, Statement as StatementCompat } from "./compat.js"; +import { Database as DatabasePromise, Statement as StatementPromise } from "./promise.js"; +import { SqliteError } from "./sqlite-error.js"; + +export { DatabaseCompat, StatementCompat, DatabasePromise, StatementPromise, NativeDatabase, NativeStatement, SqliteError, DatabaseOpts } diff --git a/bindings/javascript/packages/common/package.json b/bindings/javascript/packages/common/package.json new file mode 100644 index 000000000..4a4af4d3c --- /dev/null +++ b/bindings/javascript/packages/common/package.json @@ -0,0 +1,25 @@ +{ + "name": "@tursodatabase/database-common", + "version": "0.1.5-pre.5", + "repository": { + "type": "git", + "url": "https://github.com/tursodatabase/turso" + }, + "type": "module", + "license": "MIT", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "packageManager": "yarn@4.9.2", + "files": [ + "dist/**", + "README.md" + ], + "devDependencies": { + "typescript": "^5.9.2" + }, + "scripts": { + "tsc-build": "npm exec tsc", + "build": "npm run tsc-build", + "test": "echo 'no tests'" + } +} diff --git a/bindings/javascript/promise.ts b/bindings/javascript/packages/common/promise.ts similarity index 88% rename from bindings/javascript/promise.ts rename to bindings/javascript/packages/common/promise.ts index 04df99d9f..e81795833 100644 --- a/bindings/javascript/promise.ts +++ b/bindings/javascript/packages/common/promise.ts @@ -1,12 +1,6 @@ -import { Database as NativeDB, Statement as NativeStatement } from "#entry-point"; import { bindParams } from "./bind.js"; - import { SqliteError } from "./sqlite-error.js"; - -// Step result constants -const STEP_ROW = 1; -const STEP_DONE = 2; -const STEP_IO = 3; +import { NativeDatabase, NativeStatement, STEP_IO, STEP_ROW, STEP_DONE, DatabaseOpts } from "./types.js"; const convertibleErrorTypes = { TypeError }; const CONVERTIBLE_ERROR_PREFIX = "[TURSO_CONVERT_TYPE]"; @@ -35,7 +29,7 @@ function createErrorByName(name, message) { * Database represents a connection that can prepare and execute SQL statements. */ class Database { - db: NativeDB; + db: NativeDatabase; memory: boolean; open: boolean; private _inTransaction: boolean = false; @@ -49,19 +43,18 @@ class Database { * @param {boolean} [opts.fileMustExist=false] - If true, throws if database file does not exist. * @param {number} [opts.timeout=0] - Timeout duration in milliseconds for database operations. Defaults to 0 (no timeout). */ - constructor(path: string, opts: any = {}) { + constructor(db: NativeDatabase, opts: DatabaseOpts = {}) { opts.readonly = opts.readonly === undefined ? false : opts.readonly; opts.fileMustExist = opts.fileMustExist === undefined ? false : opts.fileMustExist; opts.timeout = opts.timeout === undefined ? 0 : opts.timeout; - const db = new NativeDB(path); - this.initialize(db, opts.path, opts.readonly); + this.initialize(db, opts.name, opts.readonly); } static create() { return Object.create(this.prototype); } - initialize(db: NativeDB, name, readonly) { + initialize(db: NativeDatabase, name, readonly) { this.db = db; this.memory = db.memory; Object.defineProperties(this, { @@ -112,22 +105,22 @@ class Database { * * @param {function} fn - The function to wrap in a transaction. */ - transaction(fn) { + transaction(fn: (...any) => Promise) { if (typeof fn !== "function") throw new TypeError("Expected first argument to be a function"); const db = this; const wrapTxn = (mode) => { - return (...bindParameters) => { - db.exec("BEGIN " + mode); + return async (...bindParameters) => { + await db.exec("BEGIN " + mode); db._inTransaction = true; try { - const result = fn(...bindParameters); - db.exec("COMMIT"); + const result = await fn(...bindParameters); + await db.exec("COMMIT"); db._inTransaction = false; return result; } catch (err) { - db.exec("ROLLBACK"); + await db.exec("ROLLBACK"); db._inTransaction = false; throw err; } @@ -147,7 +140,7 @@ class Database { return properties.default.value; } - pragma(source, options) { + async pragma(source, options) { if (options == null) options = {}; if (typeof source !== "string") @@ -158,8 +151,8 @@ class Database { const pragma = `PRAGMA ${source}`; - const stmt = this.prepare(pragma); - const results = stmt.all(); + const stmt = await this.prepare(pragma); + const results = await stmt.all(); return results; } @@ -197,13 +190,13 @@ class Database { * * @param {string} sql - The SQL statement string to execute. */ - exec(sql) { + async exec(sql) { if (!this.open) { throw new TypeError("The database connection is not open"); } try { - this.db.batch(sql); + await this.db.batchAsync(sql); } catch (err) { throw convertError(err); } @@ -228,7 +221,7 @@ class Database { /** * Closes the database connection. */ - close() { + async close() { this.db.close(); } } @@ -305,7 +298,7 @@ class Statement { bindParams(this.stmt, bindParameters); while (true) { - const stepResult = this.stmt.step(); + const stepResult = await this.stmt.stepAsync(); if (stepResult === STEP_IO) { await this.db.db.ioLoopAsync(); continue; @@ -335,7 +328,7 @@ class Statement { bindParams(this.stmt, bindParameters); while (true) { - const stepResult = this.stmt.step(); + const stepResult = await this.stmt.stepAsync(); if (stepResult === STEP_IO) { await this.db.db.ioLoopAsync(); continue; @@ -359,7 +352,7 @@ class Statement { bindParams(this.stmt, bindParameters); while (true) { - const stepResult = this.stmt.step(); + const stepResult = await this.stmt.stepAsync(); if (stepResult === STEP_IO) { await this.db.db.ioLoopAsync(); continue; @@ -384,7 +377,7 @@ class Statement { const rows: any[] = []; while (true) { - const stepResult = this.stmt.step(); + const stepResult = await this.stmt.stepAsync(); if (stepResult === STEP_IO) { await this.db.db.ioLoopAsync(); continue; @@ -421,17 +414,9 @@ class Statement { throw convertError(err); } } -} -/** - * Creates a new database connection asynchronously. - * - * @param {string} path - Path to the database file. - * @param {Object} opts - Options for database behavior. - * @returns {Promise} - A promise that resolves to a Database instance. - */ -async function connect(path: string, opts: any = {}): Promise { - return new Database(path, opts); + close() { + this.stmt.finalize(); + } } - -export { Database, SqliteError, connect } \ No newline at end of file +export { Database, Statement } \ No newline at end of file diff --git a/bindings/javascript/sqlite-error.ts b/bindings/javascript/packages/common/sqlite-error.ts similarity index 100% rename from bindings/javascript/sqlite-error.ts rename to bindings/javascript/packages/common/sqlite-error.ts diff --git a/bindings/javascript/tsconfig.json b/bindings/javascript/packages/common/tsconfig.json similarity index 71% rename from bindings/javascript/tsconfig.json rename to bindings/javascript/packages/common/tsconfig.json index 4722ef092..bf9c13271 100644 --- a/bindings/javascript/tsconfig.json +++ b/bindings/javascript/packages/common/tsconfig.json @@ -1,17 +1,14 @@ { "compilerOptions": { "skipLibCheck": true, + "declaration": true, + "declarationMap": true, "module": "esnext", "target": "esnext", "outDir": "dist/", "lib": [ "es2020" ], - "paths": { - "#entry-point": [ - "./index.js" - ] - } }, "include": [ "*" diff --git a/bindings/javascript/packages/common/types.ts b/bindings/javascript/packages/common/types.ts new file mode 100644 index 000000000..2b843bb9f --- /dev/null +++ b/bindings/javascript/packages/common/types.ts @@ -0,0 +1,46 @@ +export interface DatabaseOpts { + readonly?: boolean, + fileMustExist?: boolean, + timeout?: number + name?: string + tracing?: 'info' | 'debug' | 'trace' +} + +export interface NativeDatabase { + memory: boolean, + path: string, + new(path: string): NativeDatabase; + batchSync(sql: string); + batchAsync(sql: string): Promise; + + ioLoopSync(); + ioLoopAsync(): Promise; + + prepare(sql: string): NativeStatement; + + pluck(pluckMode: boolean); + defaultSafeIntegers(toggle: boolean); + totalChanges(): number; + changes(): number; + lastInsertRowid(): number; + close(); +} + + +// Step result constants +export const STEP_ROW = 1; +export const STEP_DONE = 2; +export const STEP_IO = 3; + +export interface NativeStatement { + stepAsync(): Promise; + stepSync(): number; + + pluck(pluckMode: boolean); + safeIntegers(toggle: boolean); + raw(toggle: boolean); + columns(): string[]; + row(): any; + reset(); + finalize(); +} \ No newline at end of file diff --git a/bindings/javascript/packages/native/README.md b/bindings/javascript/packages/native/README.md new file mode 100644 index 000000000..d5444435c --- /dev/null +++ b/bindings/javascript/packages/native/README.md @@ -0,0 +1,125 @@ +

+

Turso Database for JavaScript in Node

+

+ +

+ npm + +

+

+ Chat with other users of Turso on Discord +

+ +--- + +## About + +This package is the Turso embedded database library for JavaScript in Node. + +> **⚠️ Warning:** This software is ALPHA, only use for development, testing, and experimentation. We are working to make it production ready, but do not use it for critical data right now. + +## Features + +- **SQLite compatible:** SQLite query language and file format support ([status](https://github.com/tursodatabase/turso/blob/main/COMPAT.md)). +- **In-process**: No network overhead, runs directly in your Node.js process +- **TypeScript support**: Full TypeScript definitions included +- **Cross-platform**: Supports Linux (x86 and arm64), macOS, Windows (browser is supported in the separate package `@tursodatabase/database-browser` package) + +## Installation + +```bash +npm install @tursodatabase/database +``` + +## Getting Started + +### In-Memory Database + +```javascript +import { connect } from '@tursodatabase/database'; + +// Create an in-memory database +const db = await connect(':memory:'); + +// Create a table +await db.exec('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, email TEXT)'); + +// Insert data +const insert = db.prepare('INSERT INTO users (name, email) VALUES (?, ?)'); +await insert.run('Alice', 'alice@example.com'); +await insert.run('Bob', 'bob@example.com'); + +// Query data +const users = await db.prepare('SELECT * FROM users').all(); +console.log(users); +// Output: [ +// { id: 1, name: 'Alice', email: 'alice@example.com' }, +// { id: 2, name: 'Bob', email: 'bob@example.com' } +// ] +``` + +### File-Based Database + +```javascript +import { connect } from '@tursodatabase/database'; + +// Create or open a database file +const db = await connect('my-database.db'); + +// Create a table +await db.exec(` + CREATE TABLE IF NOT EXISTS posts ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + title TEXT NOT NULL, + content TEXT, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP + ) +`); + +// Insert a post +const insertPost = db.prepare('INSERT INTO posts (title, content) VALUES (?, ?)'); +const result = await insertPost.run('Hello World', 'This is my first blog post!'); + +console.log(`Inserted post with ID: ${result.lastInsertRowid}`); +``` + +### Transactions + +```javascript +import { connect } from '@tursodatabase/database'; + +const db = await connect('transactions.db'); + +// Using transactions for atomic operations +const transaction = db.transaction(async (users) => { + const insert = db.prepare('INSERT INTO users (name, email) VALUES (?, ?)'); + for (const user of users) { + await insert.run(user.name, user.email); + } +}); + +// Execute transaction +await transaction([ + { name: 'Alice', email: 'alice@example.com' }, + { name: 'Bob', email: 'bob@example.com' } +]); +``` + +## API Reference + +For complete API documentation, see [JavaScript API Reference](../../../../docs/javascript-api-reference.md). + +## Related Packages + +* The [@tursodatabase/serverless](https://www.npmjs.com/package/@tursodatabase/serverless) package provides a serverless driver with the same API. +* The [@tursodatabase/sync](https://www.npmjs.com/package/@tursodatabase/sync) package provides bidirectional sync between a local Turso database and Turso Cloud. + +## License + +This project is licensed under the [MIT license](../../LICENSE.md). + +## Support + +- [GitHub Issues](https://github.com/tursodatabase/turso/issues) +- [Documentation](https://docs.turso.tech) +- [Discord Community](https://tur.so/discord) diff --git a/bindings/javascript/packages/native/compat.test.ts b/bindings/javascript/packages/native/compat.test.ts new file mode 100644 index 000000000..c64d4fc79 --- /dev/null +++ b/bindings/javascript/packages/native/compat.test.ts @@ -0,0 +1,67 @@ +import { unlinkSync } from "node:fs"; +import { expect, test } from 'vitest' +import { Database } from './compat.js' + +test('in-memory db', () => { + const db = new Database(":memory:"); + db.exec("CREATE TABLE t(x)"); + db.exec("INSERT INTO t VALUES (1), (2), (3)"); + const stmt = db.prepare("SELECT * FROM t WHERE x % 2 = ?"); + const rows = stmt.all([1]); + expect(rows).toEqual([{ x: 1 }, { x: 3 }]); +}) + +test('on-disk db', () => { + const path = `test-${(Math.random() * 10000) | 0}.db`; + try { + const db1 = new Database(path); + db1.exec("CREATE TABLE t(x)"); + db1.exec("INSERT INTO t VALUES (1), (2), (3)"); + const stmt1 = db1.prepare("SELECT * FROM t WHERE x % 2 = ?"); + expect(stmt1.columns()).toEqual([{ name: "x", column: null, database: null, table: null, type: null }]); + const rows1 = stmt1.all([1]); + expect(rows1).toEqual([{ x: 1 }, { x: 3 }]); + db1.close(); + + const db2 = new Database(path); + const stmt2 = db2.prepare("SELECT * FROM t WHERE x % 2 = ?"); + expect(stmt2.columns()).toEqual([{ name: "x", column: null, database: null, table: null, type: null }]); + const rows2 = stmt2.all([1]); + expect(rows2).toEqual([{ x: 1 }, { x: 3 }]); + db2.close(); + } finally { + unlinkSync(path); + unlinkSync(`${path}-wal`); + } +}) + +test('attach', () => { + const path1 = `test-${(Math.random() * 10000) | 0}.db`; + const path2 = `test-${(Math.random() * 10000) | 0}.db`; + try { + const db1 = new Database(path1); + db1.exec("CREATE TABLE t(x)"); + db1.exec("INSERT INTO t VALUES (1), (2), (3)"); + const db2 = new Database(path2); + db2.exec("CREATE TABLE q(x)"); + db2.exec("INSERT INTO q VALUES (4), (5), (6)"); + + db1.exec(`ATTACH '${path2}' as secondary`); + + const stmt = db1.prepare("SELECT * FROM t UNION ALL SELECT * FROM secondary.q"); + expect(stmt.columns()).toEqual([{ name: "x", column: null, database: null, table: null, type: null }]); + const rows = stmt.all([1]); + expect(rows).toEqual([{ x: 1 }, { x: 2 }, { x: 3 }, { x: 4 }, { x: 5 }, { x: 6 }]); + } finally { + unlinkSync(path1); + unlinkSync(`${path1}-wal`); + unlinkSync(path2); + unlinkSync(`${path2}-wal`); + } +}) + +test('blobs', () => { + const db = new Database(":memory:"); + const rows = db.prepare("SELECT x'1020' as x").all(); + expect(rows).toEqual([{ x: Buffer.from([16, 32]) }]) +}) \ No newline at end of file diff --git a/bindings/javascript/packages/native/compat.ts b/bindings/javascript/packages/native/compat.ts new file mode 100644 index 000000000..105d69e85 --- /dev/null +++ b/bindings/javascript/packages/native/compat.ts @@ -0,0 +1,10 @@ +import { DatabaseCompat, NativeDatabase, SqliteError, DatabaseOpts } from "@tursodatabase/database-common" +import { Database as NativeDB } from "#index"; + +class Database extends DatabaseCompat { + constructor(path: string, opts: DatabaseOpts = {}) { + super(new NativeDB(path, { tracing: opts.tracing }) as unknown as NativeDatabase, opts) + } +} + +export { Database, SqliteError } diff --git a/bindings/javascript/index.d.ts b/bindings/javascript/packages/native/index.d.ts similarity index 81% rename from bindings/javascript/index.d.ts rename to bindings/javascript/packages/native/index.d.ts index 14f852afa..1c510cfdc 100644 --- a/bindings/javascript/index.d.ts +++ b/bindings/javascript/packages/native/index.d.ts @@ -8,13 +8,13 @@ export declare class Database { * # Arguments * * `path` - The path to the database file. */ - constructor(path: string) + constructor(path: string, opts?: DatabaseOpts | undefined | null) /** Returns whether the database is in memory-only mode. */ get memory(): boolean /** Returns whether the database connection is open. */ get open(): boolean /** - * Executes a batch of SQL statements. + * Executes a batch of SQL statements on main thread * * # Arguments * @@ -22,7 +22,17 @@ export declare class Database { * * # Returns */ - batch(sql: string): void + batchSync(sql: string): void + /** + * Executes a batch of SQL statements outside of main thread + * + * # Arguments + * + * * `sql` - The SQL statements to execute. + * + * # Returns + */ + batchAsync(sql: string): Promise /** * Prepares a statement for execution. * @@ -105,10 +115,15 @@ export declare class Statement { */ bindAt(index: number, value: unknown): void /** - * Step the statement and return result code: + * Step the statement and return result code (executed on the main thread): * 1 = Row available, 2 = Done, 3 = I/O needed */ - step(): number + stepSync(): number + /** + * Step the statement and return result code (executed on the background thread): + * 1 = Row available, 2 = Done, 3 = I/O needed + */ + stepAsync(): Promise /** Get the current row data according to the presentation mode */ row(): unknown /** Sets the presentation mode to raw. */ @@ -128,3 +143,7 @@ export declare class Statement { /** Finalizes the statement. */ finalize(): void } + +export interface DatabaseOpts { + tracing?: string +} diff --git a/bindings/javascript/packages/native/index.js b/bindings/javascript/packages/native/index.js new file mode 100644 index 000000000..d69167a1a --- /dev/null +++ b/bindings/javascript/packages/native/index.js @@ -0,0 +1,513 @@ +// prettier-ignore +/* eslint-disable */ +// @ts-nocheck +/* auto-generated by NAPI-RS */ + +import { createRequire } from 'node:module' +const require = createRequire(import.meta.url) +const __dirname = new URL('.', import.meta.url).pathname + +const { readFileSync } = require('node:fs') +let nativeBinding = null +const loadErrors = [] + +const isMusl = () => { + let musl = false + if (process.platform === 'linux') { + musl = isMuslFromFilesystem() + if (musl === null) { + musl = isMuslFromReport() + } + if (musl === null) { + musl = isMuslFromChildProcess() + } + } + return musl +} + +const isFileMusl = (f) => f.includes('libc.musl-') || f.includes('ld-musl-') + +const isMuslFromFilesystem = () => { + try { + return readFileSync('/usr/bin/ldd', 'utf-8').includes('musl') + } catch { + return null + } +} + +const isMuslFromReport = () => { + let report = null + if (typeof process.report?.getReport === 'function') { + process.report.excludeNetwork = true + report = process.report.getReport() + } + if (!report) { + return null + } + if (report.header && report.header.glibcVersionRuntime) { + return false + } + if (Array.isArray(report.sharedObjects)) { + if (report.sharedObjects.some(isFileMusl)) { + return true + } + } + return false +} + +const isMuslFromChildProcess = () => { + try { + return require('child_process').execSync('ldd --version', { encoding: 'utf8' }).includes('musl') + } catch (e) { + // If we reach this case, we don't know if the system is musl or not, so is better to just fallback to false + return false + } +} + +function requireNative() { + if (process.env.NAPI_RS_NATIVE_LIBRARY_PATH) { + try { + nativeBinding = require(process.env.NAPI_RS_NATIVE_LIBRARY_PATH); + } catch (err) { + loadErrors.push(err) + } + } else if (process.platform === 'android') { + if (process.arch === 'arm64') { + try { + return require('./turso.android-arm64.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@tursodatabase/database-android-arm64') + const bindingPackageVersion = require('@tursodatabase/database-android-arm64/package.json').version + if (bindingPackageVersion !== '0.1.5-pre.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.5-pre.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + } else if (process.arch === 'arm') { + try { + return require('./turso.android-arm-eabi.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@tursodatabase/database-android-arm-eabi') + const bindingPackageVersion = require('@tursodatabase/database-android-arm-eabi/package.json').version + if (bindingPackageVersion !== '0.1.5-pre.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.5-pre.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + } else { + loadErrors.push(new Error(`Unsupported architecture on Android ${process.arch}`)) + } + } else if (process.platform === 'win32') { + if (process.arch === 'x64') { + try { + return require('./turso.win32-x64-msvc.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@tursodatabase/database-win32-x64-msvc') + const bindingPackageVersion = require('@tursodatabase/database-win32-x64-msvc/package.json').version + if (bindingPackageVersion !== '0.1.5-pre.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.5-pre.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + } else if (process.arch === 'ia32') { + try { + return require('./turso.win32-ia32-msvc.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@tursodatabase/database-win32-ia32-msvc') + const bindingPackageVersion = require('@tursodatabase/database-win32-ia32-msvc/package.json').version + if (bindingPackageVersion !== '0.1.5-pre.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.5-pre.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + } else if (process.arch === 'arm64') { + try { + return require('./turso.win32-arm64-msvc.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@tursodatabase/database-win32-arm64-msvc') + const bindingPackageVersion = require('@tursodatabase/database-win32-arm64-msvc/package.json').version + if (bindingPackageVersion !== '0.1.5-pre.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.5-pre.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + } else { + loadErrors.push(new Error(`Unsupported architecture on Windows: ${process.arch}`)) + } + } else if (process.platform === 'darwin') { + try { + return require('./turso.darwin-universal.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@tursodatabase/database-darwin-universal') + const bindingPackageVersion = require('@tursodatabase/database-darwin-universal/package.json').version + if (bindingPackageVersion !== '0.1.5-pre.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.5-pre.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + if (process.arch === 'x64') { + try { + return require('./turso.darwin-x64.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@tursodatabase/database-darwin-x64') + const bindingPackageVersion = require('@tursodatabase/database-darwin-x64/package.json').version + if (bindingPackageVersion !== '0.1.5-pre.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.5-pre.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + } else if (process.arch === 'arm64') { + try { + return require('./turso.darwin-arm64.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@tursodatabase/database-darwin-arm64') + const bindingPackageVersion = require('@tursodatabase/database-darwin-arm64/package.json').version + if (bindingPackageVersion !== '0.1.5-pre.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.5-pre.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + } else { + loadErrors.push(new Error(`Unsupported architecture on macOS: ${process.arch}`)) + } + } else if (process.platform === 'freebsd') { + if (process.arch === 'x64') { + try { + return require('./turso.freebsd-x64.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@tursodatabase/database-freebsd-x64') + const bindingPackageVersion = require('@tursodatabase/database-freebsd-x64/package.json').version + if (bindingPackageVersion !== '0.1.5-pre.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.5-pre.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + } else if (process.arch === 'arm64') { + try { + return require('./turso.freebsd-arm64.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@tursodatabase/database-freebsd-arm64') + const bindingPackageVersion = require('@tursodatabase/database-freebsd-arm64/package.json').version + if (bindingPackageVersion !== '0.1.5-pre.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.5-pre.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + } else { + loadErrors.push(new Error(`Unsupported architecture on FreeBSD: ${process.arch}`)) + } + } else if (process.platform === 'linux') { + if (process.arch === 'x64') { + if (isMusl()) { + try { + return require('./turso.linux-x64-musl.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@tursodatabase/database-linux-x64-musl') + const bindingPackageVersion = require('@tursodatabase/database-linux-x64-musl/package.json').version + if (bindingPackageVersion !== '0.1.5-pre.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.5-pre.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + } else { + try { + return require('./turso.linux-x64-gnu.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@tursodatabase/database-linux-x64-gnu') + const bindingPackageVersion = require('@tursodatabase/database-linux-x64-gnu/package.json').version + if (bindingPackageVersion !== '0.1.5-pre.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.5-pre.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + } + } else if (process.arch === 'arm64') { + if (isMusl()) { + try { + return require('./turso.linux-arm64-musl.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@tursodatabase/database-linux-arm64-musl') + const bindingPackageVersion = require('@tursodatabase/database-linux-arm64-musl/package.json').version + if (bindingPackageVersion !== '0.1.5-pre.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.5-pre.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + } else { + try { + return require('./turso.linux-arm64-gnu.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@tursodatabase/database-linux-arm64-gnu') + const bindingPackageVersion = require('@tursodatabase/database-linux-arm64-gnu/package.json').version + if (bindingPackageVersion !== '0.1.5-pre.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.5-pre.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + } + } else if (process.arch === 'arm') { + if (isMusl()) { + try { + return require('./turso.linux-arm-musleabihf.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@tursodatabase/database-linux-arm-musleabihf') + const bindingPackageVersion = require('@tursodatabase/database-linux-arm-musleabihf/package.json').version + if (bindingPackageVersion !== '0.1.5-pre.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.5-pre.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + } else { + try { + return require('./turso.linux-arm-gnueabihf.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@tursodatabase/database-linux-arm-gnueabihf') + const bindingPackageVersion = require('@tursodatabase/database-linux-arm-gnueabihf/package.json').version + if (bindingPackageVersion !== '0.1.5-pre.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.5-pre.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + } + } else if (process.arch === 'riscv64') { + if (isMusl()) { + try { + return require('./turso.linux-riscv64-musl.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@tursodatabase/database-linux-riscv64-musl') + const bindingPackageVersion = require('@tursodatabase/database-linux-riscv64-musl/package.json').version + if (bindingPackageVersion !== '0.1.5-pre.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.5-pre.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + } else { + try { + return require('./turso.linux-riscv64-gnu.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@tursodatabase/database-linux-riscv64-gnu') + const bindingPackageVersion = require('@tursodatabase/database-linux-riscv64-gnu/package.json').version + if (bindingPackageVersion !== '0.1.5-pre.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.5-pre.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + } + } else if (process.arch === 'ppc64') { + try { + return require('./turso.linux-ppc64-gnu.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@tursodatabase/database-linux-ppc64-gnu') + const bindingPackageVersion = require('@tursodatabase/database-linux-ppc64-gnu/package.json').version + if (bindingPackageVersion !== '0.1.5-pre.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.5-pre.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + } else if (process.arch === 's390x') { + try { + return require('./turso.linux-s390x-gnu.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@tursodatabase/database-linux-s390x-gnu') + const bindingPackageVersion = require('@tursodatabase/database-linux-s390x-gnu/package.json').version + if (bindingPackageVersion !== '0.1.5-pre.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.5-pre.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + } else { + loadErrors.push(new Error(`Unsupported architecture on Linux: ${process.arch}`)) + } + } else if (process.platform === 'openharmony') { + if (process.arch === 'arm64') { + try { + return require('./turso.openharmony-arm64.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@tursodatabase/database-openharmony-arm64') + const bindingPackageVersion = require('@tursodatabase/database-openharmony-arm64/package.json').version + if (bindingPackageVersion !== '0.1.5-pre.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.5-pre.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + } else if (process.arch === 'x64') { + try { + return require('./turso.openharmony-x64.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@tursodatabase/database-openharmony-x64') + const bindingPackageVersion = require('@tursodatabase/database-openharmony-x64/package.json').version + if (bindingPackageVersion !== '0.1.5-pre.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.5-pre.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + } else if (process.arch === 'arm') { + try { + return require('./turso.openharmony-arm.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@tursodatabase/database-openharmony-arm') + const bindingPackageVersion = require('@tursodatabase/database-openharmony-arm/package.json').version + if (bindingPackageVersion !== '0.1.5-pre.3' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.5-pre.3 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + } else { + loadErrors.push(new Error(`Unsupported architecture on OpenHarmony: ${process.arch}`)) + } + } else { + loadErrors.push(new Error(`Unsupported OS: ${process.platform}, architecture: ${process.arch}`)) + } +} + +nativeBinding = requireNative() + +if (!nativeBinding || process.env.NAPI_RS_FORCE_WASI) { + try { + nativeBinding = require('./turso.wasi.cjs') + } catch (err) { + if (process.env.NAPI_RS_FORCE_WASI) { + loadErrors.push(err) + } + } + if (!nativeBinding) { + try { + nativeBinding = require('@tursodatabase/database-wasm32-wasi') + } catch (err) { + if (process.env.NAPI_RS_FORCE_WASI) { + loadErrors.push(err) + } + } + } +} + +if (!nativeBinding) { + if (loadErrors.length > 0) { + throw new Error( + `Cannot find native binding. ` + + `npm has a bug related to optional dependencies (https://github.com/npm/cli/issues/4828). ` + + 'Please try `npm i` again after removing both package-lock.json and node_modules directory.', + { cause: loadErrors } + ) + } + throw new Error(`Failed to load native binding`) +} + +const { Database, Statement } = nativeBinding +export { Database } +export { Statement } diff --git a/bindings/javascript/packages/native/package.json b/bindings/javascript/packages/native/package.json new file mode 100644 index 000000000..abd6cfe97 --- /dev/null +++ b/bindings/javascript/packages/native/package.json @@ -0,0 +1,52 @@ +{ + "name": "@tursodatabase/database", + "version": "0.1.5-pre.5", + "repository": { + "type": "git", + "url": "https://github.com/tursodatabase/turso" + }, + "license": "MIT", + "module": "./dist/promise.js", + "main": "./dist/promise.js", + "type": "module", + "exports": { + ".": "./dist/promise.js", + "./compat": "./dist/compat.js" + }, + "files": [ + "index.js", + "dist/**", + "README.md" + ], + "packageManager": "yarn@4.9.2", + "devDependencies": { + "@napi-rs/cli": "^3.1.5", + "@types/node": "^24.3.1", + "typescript": "^5.9.2", + "vitest": "^3.2.4" + }, + "scripts": { + "napi-build": "napi build --platform --release --esm --manifest-path ../../Cargo.toml --output-dir .", + "napi-dirs": "napi create-npm-dirs", + "napi-artifacts": "napi artifacts --output-dir .", + "tsc-build": "npm exec tsc", + "build": "npm run napi-build && npm run tsc-build", + "test": "vitest --run", + "prepublishOnly": "npm run napi-dirs && npm run napi-artifacts && napi prepublish -t npm" + }, + "napi": { + "binaryName": "turso", + "targets": [ + "x86_64-unknown-linux-gnu", + "x86_64-pc-windows-msvc", + "universal-apple-darwin", + "aarch64-unknown-linux-gnu" + ] + }, + "dependencies": { + "@tursodatabase/database-common": "^0.1.5-pre.5" + }, + "imports": { + "#index": "./index.js" + } +} diff --git a/bindings/javascript/packages/native/promise.test.ts b/bindings/javascript/packages/native/promise.test.ts new file mode 100644 index 000000000..d75e3728e --- /dev/null +++ b/bindings/javascript/packages/native/promise.test.ts @@ -0,0 +1,107 @@ +import { unlinkSync } from "node:fs"; +import { expect, test } from 'vitest' +import { connect } from './promise.js' + +test('in-memory db', async () => { + const db = await connect(":memory:"); + await db.exec("CREATE TABLE t(x)"); + await db.exec("INSERT INTO t VALUES (1), (2), (3)"); + const stmt = db.prepare("SELECT * FROM t WHERE x % 2 = ?"); + const rows = await stmt.all([1]); + expect(rows).toEqual([{ x: 1 }, { x: 3 }]); +}) + +test('on-disk db', async () => { + const path = `test-${(Math.random() * 10000) | 0}.db`; + try { + const db1 = await connect(path); + await db1.exec("CREATE TABLE t(x)"); + await db1.exec("INSERT INTO t VALUES (1), (2), (3)"); + const stmt1 = db1.prepare("SELECT * FROM t WHERE x % 2 = ?"); + expect(stmt1.columns()).toEqual([{ name: "x", column: null, database: null, table: null, type: null }]); + const rows1 = await stmt1.all([1]); + expect(rows1).toEqual([{ x: 1 }, { x: 3 }]); + db1.close(); + + const db2 = await connect(path); + const stmt2 = db2.prepare("SELECT * FROM t WHERE x % 2 = ?"); + expect(stmt2.columns()).toEqual([{ name: "x", column: null, database: null, table: null, type: null }]); + const rows2 = await stmt2.all([1]); + expect(rows2).toEqual([{ x: 1 }, { x: 3 }]); + db2.close(); + } finally { + unlinkSync(path); + unlinkSync(`${path}-wal`); + } +}) + +test('attach', async () => { + const path1 = `test-${(Math.random() * 10000) | 0}.db`; + const path2 = `test-${(Math.random() * 10000) | 0}.db`; + try { + const db1 = await connect(path1); + await db1.exec("CREATE TABLE t(x)"); + await db1.exec("INSERT INTO t VALUES (1), (2), (3)"); + const db2 = await connect(path2); + await db2.exec("CREATE TABLE q(x)"); + await db2.exec("INSERT INTO q VALUES (4), (5), (6)"); + + await db1.exec(`ATTACH '${path2}' as secondary`); + + const stmt = db1.prepare("SELECT * FROM t UNION ALL SELECT * FROM secondary.q"); + expect(stmt.columns()).toEqual([{ name: "x", column: null, database: null, table: null, type: null }]); + const rows = await stmt.all([1]); + expect(rows).toEqual([{ x: 1 }, { x: 2 }, { x: 3 }, { x: 4 }, { x: 5 }, { x: 6 }]); + } finally { + unlinkSync(path1); + unlinkSync(`${path1}-wal`); + unlinkSync(path2); + unlinkSync(`${path2}-wal`); + } +}) + +test('blobs', async () => { + const db = await connect(":memory:"); + const rows = await db.prepare("SELECT x'1020' as x").all(); + expect(rows).toEqual([{ x: Buffer.from([16, 32]) }]) +}) + + +test('example-1', async () => { + const db = await connect(':memory:'); + await db.exec('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, email TEXT)'); + + const insert = db.prepare('INSERT INTO users (name, email) VALUES (?, ?)'); + await insert.run('Alice', 'alice@example.com'); + await insert.run('Bob', 'bob@example.com'); + + const users = await db.prepare('SELECT * FROM users').all(); + expect(users).toEqual([ + { id: 1, name: 'Alice', email: 'alice@example.com' }, + { id: 2, name: 'Bob', email: 'bob@example.com' } + ]); +}) + +test('example-2', async () => { + const db = await connect(':memory:'); + await db.exec('CREATE TABLE users (name, email)'); + // Using transactions for atomic operations + const transaction = db.transaction(async (users) => { + const insert = db.prepare('INSERT INTO users (name, email) VALUES (?, ?)'); + for (const user of users) { + await insert.run(user.name, user.email); + } + }); + + // Execute transaction + await transaction([ + { name: 'Alice', email: 'alice@example.com' }, + { name: 'Bob', email: 'bob@example.com' } + ]); + + const rows = await db.prepare('SELECT * FROM users').all(); + expect(rows).toEqual([ + { name: 'Alice', email: 'alice@example.com' }, + { name: 'Bob', email: 'bob@example.com' } + ]); +}) \ No newline at end of file diff --git a/bindings/javascript/packages/native/promise.ts b/bindings/javascript/packages/native/promise.ts new file mode 100644 index 000000000..0131381c0 --- /dev/null +++ b/bindings/javascript/packages/native/promise.ts @@ -0,0 +1,21 @@ +import { DatabasePromise, NativeDatabase, SqliteError, DatabaseOpts } from "@tursodatabase/database-common" +import { Database as NativeDB } from "#index"; + +class Database extends DatabasePromise { + constructor(path: string, opts: DatabaseOpts = {}) { + super(new NativeDB(path, { tracing: opts.tracing }) as unknown as NativeDatabase, opts) + } +} + +/** + * Creates a new database connection asynchronously. + * + * @param {string} path - Path to the database file. + * @param {Object} opts - Options for database behavior. + * @returns {Promise} - A promise that resolves to a Database instance. + */ +async function connect(path: string, opts: any = {}): Promise { + return new Database(path, opts); +} + +export { connect, Database, SqliteError } diff --git a/bindings/javascript/packages/native/tsconfig.json b/bindings/javascript/packages/native/tsconfig.json new file mode 100644 index 000000000..b46abc167 --- /dev/null +++ b/bindings/javascript/packages/native/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "skipLibCheck": true, + "declaration": true, + "declarationMap": true, + "module": "nodenext", + "target": "esnext", + "outDir": "dist/", + "lib": [ + "es2020" + ], + "paths": { + "#index": [ + "./index.js" + ] + } + }, + "include": [ + "*" + ] +} \ No newline at end of file diff --git a/bindings/javascript/perf/package-lock.json b/bindings/javascript/perf/package-lock.json index 8d882350b..bf737b714 100644 --- a/bindings/javascript/perf/package-lock.json +++ b/bindings/javascript/perf/package-lock.json @@ -6,28 +6,34 @@ "": { "name": "turso-perf", "dependencies": { - "@tursodatabase/database": "..", + "@tursodatabase/database": "../packages/native", "better-sqlite3": "^9.5.0", "mitata": "^0.1.11" } }, "..": { + "workspaces": [ + "packages/core", + "packages/native", + "packages/browser" + ] + }, + "../packages/native": { "name": "@tursodatabase/database", - "version": "0.1.4-pre.4", + "version": "0.1.5-pre.3", "license": "MIT", - "devDependencies": { - "@napi-rs/cli": "^3.0.4", - "@napi-rs/wasm-runtime": "^1.0.1", - "ava": "^6.0.1", - "better-sqlite3": "^11.9.1", - "typescript": "^5.9.2" + "dependencies": { + "@tursodatabase/database-common": "^0.1.5-pre.3" }, - "engines": { - "node": ">= 10" + "devDependencies": { + "@napi-rs/cli": "^3.1.5", + "@types/node": "^24.3.1", + "typescript": "^5.9.2", + "vitest": "^3.2.4" } }, "node_modules/@tursodatabase/database": { - "resolved": "..", + "resolved": "../packages/native", "link": true }, "node_modules/base64-js": { diff --git a/bindings/javascript/perf/package.json b/bindings/javascript/perf/package.json index 83210e7f5..93e3d789e 100644 --- a/bindings/javascript/perf/package.json +++ b/bindings/javascript/perf/package.json @@ -2,9 +2,10 @@ "name": "turso-perf", "type": "module", "private": true, + "type": "module", "dependencies": { "better-sqlite3": "^9.5.0", - "@tursodatabase/database": "..", + "@tursodatabase/database": "../packages/native", "mitata": "^0.1.11" } } diff --git a/bindings/javascript/perf/perf-turso.js b/bindings/javascript/perf/perf-turso.js index 24c2fad72..092730265 100644 --- a/bindings/javascript/perf/perf-turso.js +++ b/bindings/javascript/perf/perf-turso.js @@ -1,6 +1,6 @@ import { run, bench, group, baseline } from 'mitata'; -import Database from '@tursodatabase/database'; +import { Database } from '@tursodatabase/database/compat'; const db = new Database(':memory:'); diff --git a/bindings/javascript/src/browser.rs b/bindings/javascript/src/browser.rs new file mode 100644 index 000000000..f9c6bffa9 --- /dev/null +++ b/bindings/javascript/src/browser.rs @@ -0,0 +1,254 @@ +use std::sync::Arc; + +use napi::bindgen_prelude::*; +use napi_derive::napi; +use turso_core::{storage::database::DatabaseFile, Clock, File, Instant, IO}; + +use crate::{init_tracing, is_memory, Database, DatabaseOpts}; + +pub struct NoopTask; + +impl Task for NoopTask { + type Output = (); + type JsValue = (); + fn compute(&mut self) -> Result { + Ok(()) + } + fn resolve(&mut self, _: Env, _: Self::Output) -> Result { + Ok(()) + } +} + +#[napi] +/// turso-db in the the browser requires explicit thread pool initialization +/// so, we just put no-op task on the thread pool and force emnapi to allocate web worker +pub fn init_thread_pool() -> napi::Result> { + Ok(AsyncTask::new(NoopTask)) +} + +pub struct ConnectTask { + path: String, + is_memory: bool, + io: Arc, +} + +pub struct ConnectResult { + db: Arc, + conn: Arc, +} + +unsafe impl Send for ConnectResult {} + +impl Task for ConnectTask { + type Output = ConnectResult; + type JsValue = Database; + + fn compute(&mut self) -> Result { + let file = self + .io + .open_file(&self.path, turso_core::OpenFlags::Create, false) + .map_err(|e| Error::new(Status::GenericFailure, format!("Failed to open file: {e}")))?; + + let db_file = Arc::new(DatabaseFile::new(file)); + let db = turso_core::Database::open(self.io.clone(), &self.path, db_file, false, true) + .map_err(|e| { + Error::new( + Status::GenericFailure, + format!("Failed to open database: {e}"), + ) + })?; + + let conn = db + .connect() + .map_err(|e| Error::new(Status::GenericFailure, format!("Failed to connect: {e}")))?; + + Ok(ConnectResult { db, conn }) + } + + fn resolve(&mut self, _: Env, result: Self::Output) -> Result { + Ok(Database::create( + Some(result.db), + self.io.clone(), + result.conn, + self.is_memory, + )) + } +} + +#[napi] +// we offload connect to the web-worker because: +// 1. browser main-thread do not support Atomic.wait operations +// 2. turso-db use blocking IO [io.wait_for_completion(c)] in few places during initialization path +// +// so, we offload connect to the worker thread +pub fn connect(path: String, opts: Option) -> Result> { + if let Some(opts) = opts { + init_tracing(opts.tracing); + } + let task = if is_memory(&path) { + ConnectTask { + io: Arc::new(turso_core::MemoryIO::new()), + is_memory: true, + path, + } + } else { + let io = Arc::new(Opfs::new()?); + ConnectTask { + io, + is_memory: false, + path, + } + }; + Ok(AsyncTask::new(task)) +} +#[napi] +#[derive(Clone)] +pub struct Opfs; + +#[napi] +#[derive(Clone)] +struct OpfsFile { + handle: i32, +} + +#[napi] +impl Opfs { + #[napi(constructor)] + pub fn new() -> napi::Result { + Ok(Self) + } +} + +impl Clock for Opfs { + fn now(&self) -> Instant { + Instant { secs: 0, micros: 0 } // TODO + } +} + +#[link(wasm_import_module = "env")] +extern "C" { + fn lookup_file(path: *const u8, path_len: usize) -> i32; + fn read(handle: i32, buffer: *mut u8, buffer_len: usize, offset: i32) -> i32; + fn write(handle: i32, buffer: *const u8, buffer_len: usize, offset: i32) -> i32; + fn sync(handle: i32) -> i32; + fn truncate(handle: i32, length: usize) -> i32; + fn size(handle: i32) -> i32; + fn is_web_worker() -> bool; +} + +fn is_web_worker_safe() -> bool { + unsafe { is_web_worker() } +} + +impl IO for Opfs { + fn open_file( + &self, + path: &str, + _: turso_core::OpenFlags, + _: bool, + ) -> turso_core::Result> { + tracing::info!("open_file: {}", path); + let result = unsafe { lookup_file(path.as_ptr(), path.len()) }; + if result >= 0 { + Ok(Arc::new(OpfsFile { handle: result })) + } else if result == -404 { + Err(turso_core::LimboError::InternalError( + "files must be created in advance for OPFS IO".to_string(), + )) + } else { + Err(turso_core::LimboError::InternalError(format!( + "unexpected file lookup error: {result}" + ))) + } + } + + fn remove_file(&self, _: &str) -> turso_core::Result<()> { + Ok(()) + } +} + +impl File for OpfsFile { + fn lock_file(&self, _: bool) -> turso_core::Result<()> { + Ok(()) + } + + fn unlock_file(&self) -> turso_core::Result<()> { + Ok(()) + } + + fn pread( + &self, + pos: u64, + c: turso_core::Completion, + ) -> turso_core::Result { + assert!( + is_web_worker_safe(), + "opfs must be used only from web worker for now" + ); + tracing::debug!("pread({}): pos={}", self.handle, pos); + let handle = self.handle; + let read_c = c.as_read(); + let buffer = read_c.buf_arc(); + let buffer = buffer.as_mut_slice(); + let result = unsafe { read(handle, buffer.as_mut_ptr(), buffer.len(), pos as i32) }; + c.complete(result as i32); + Ok(c) + } + + fn pwrite( + &self, + pos: u64, + buffer: Arc, + c: turso_core::Completion, + ) -> turso_core::Result { + assert!( + is_web_worker_safe(), + "opfs must be used only from web worker for now" + ); + tracing::debug!("pwrite({}): pos={}", self.handle, pos); + let handle = self.handle; + let buffer = buffer.as_slice(); + let result = unsafe { write(handle, buffer.as_ptr(), buffer.len(), pos as i32) }; + c.complete(result as i32); + Ok(c) + } + + fn sync(&self, c: turso_core::Completion) -> turso_core::Result { + assert!( + is_web_worker_safe(), + "opfs must be used only from web worker for now" + ); + tracing::debug!("sync({})", self.handle); + let handle = self.handle; + let result = unsafe { sync(handle) }; + c.complete(result as i32); + Ok(c) + } + + fn truncate( + &self, + len: u64, + c: turso_core::Completion, + ) -> turso_core::Result { + assert!( + is_web_worker_safe(), + "opfs must be used only from web worker for now" + ); + tracing::debug!("truncate({}): len={}", self.handle, len); + let handle = self.handle; + let result = unsafe { truncate(handle, len as usize) }; + c.complete(result as i32); + Ok(c) + } + + fn size(&self) -> turso_core::Result { + assert!( + is_web_worker_safe(), + "size can be called only from web worker context" + ); + tracing::debug!("size({})", self.handle); + let handle = self.handle; + let result = unsafe { size(handle) }; + Ok(result as u64) + } +} diff --git a/bindings/javascript/src/lib.rs b/bindings/javascript/src/lib.rs index 3b0d8a466..928b475ef 100644 --- a/bindings/javascript/src/lib.rs +++ b/bindings/javascript/src/lib.rs @@ -10,14 +10,20 @@ //! - Iterating through query results //! - Managing the I/O event loop +#[cfg(feature = "browser")] +pub mod browser; + use napi::bindgen_prelude::*; use napi::{Env, Task}; use napi_derive::napi; +use std::sync::OnceLock; use std::{ cell::{Cell, RefCell}, num::NonZeroUsize, sync::Arc, }; +use tracing_subscriber::filter::LevelFilter; +use tracing_subscriber::fmt::format::FmtSpan; /// Step result constants const STEP_ROW: u32 = 1; @@ -38,12 +44,107 @@ enum PresentationMode { pub struct Database { _db: Option>, io: Arc, - conn: Arc, + conn: Option>, is_memory: bool, is_open: Cell, default_safe_integers: Cell, } +pub(crate) fn is_memory(path: &str) -> bool { + path == ":memory:" +} + +static TRACING_INIT: OnceLock<()> = OnceLock::new(); +pub(crate) fn init_tracing(level_filter: Option) { + let Some(level_filter) = level_filter else { + return; + }; + let level_filter = match level_filter.as_ref() { + "info" => LevelFilter::INFO, + "debug" => LevelFilter::DEBUG, + "trace" => LevelFilter::TRACE, + _ => return, + }; + TRACING_INIT.get_or_init(|| { + tracing_subscriber::fmt() + .with_ansi(false) + .with_thread_ids(true) + .with_span_events(FmtSpan::ACTIVE) + .with_max_level(level_filter) + .init(); + }); +} + +pub enum DbTask { + Batch { + conn: Arc, + sql: String, + }, + Step { + stmt: Arc>>, + }, +} + +unsafe impl Send for DbTask {} + +impl Task for DbTask { + type Output = u32; + type JsValue = u32; + + fn compute(&mut self) -> Result { + match self { + DbTask::Batch { conn, sql } => { + batch_sync(conn, sql)?; + Ok(0) + } + DbTask::Step { stmt } => step_sync(stmt), + } + } + + fn resolve(&mut self, _: Env, output: Self::Output) -> Result { + Ok(output) + } +} + +#[napi(object)] +pub struct DatabaseOpts { + pub tracing: Option, +} + +fn batch_sync(conn: &Arc, sql: &str) -> napi::Result<()> { + conn.prepare_execute_batch(sql).map_err(|e| { + Error::new( + Status::GenericFailure, + format!("Failed to execute batch: {e}"), + ) + })?; + Ok(()) +} + +fn step_sync(stmt: &Arc>>) -> napi::Result { + let mut stmt_ref = stmt.borrow_mut(); + let stmt = stmt_ref + .as_mut() + .ok_or_else(|| Error::new(Status::GenericFailure, "Statement has been finalized"))?; + + match stmt.step() { + Ok(turso_core::StepResult::Row) => Ok(STEP_ROW), + Ok(turso_core::StepResult::IO) => Ok(STEP_IO), + Ok(turso_core::StepResult::Done) => Ok(STEP_DONE), + Ok(turso_core::StepResult::Interrupt) => Err(Error::new( + Status::GenericFailure, + "Statement was interrupted", + )), + Ok(turso_core::StepResult::Busy) => { + Err(Error::new(Status::GenericFailure, "Database is busy")) + } + Err(e) => Err(Error::new( + Status::GenericFailure, + format!("Step failed: {e}"), + )), + } +} + #[napi] impl Database { /// Creates a new database instance. @@ -51,9 +152,11 @@ impl Database { /// # Arguments /// * `path` - The path to the database file. #[napi(constructor)] - pub fn new(path: String) -> Result { - let is_memory = path == ":memory:"; - let io: Arc = if is_memory { + pub fn new(path: String, opts: Option) -> Result { + if let Some(opts) = opts { + init_tracing(opts.tracing); + } + let io: Arc = if is_memory(&path) { Arc::new(turso_core::MemoryIO::new()) } else { Arc::new(turso_core::PlatformIO::new().map_err(|e| { @@ -61,6 +164,11 @@ impl Database { })?) }; + #[cfg(feature = "browser")] + if !is_memory(&path) { + return Err(Error::new(Status::GenericFailure, "sync constructor is not supported for FS-backed databases in the WASM. Use async connect(...) method instead".to_string())); + } + let file = io .open_file(&path, turso_core::OpenFlags::Create, false) .map_err(|e| Error::new(Status::GenericFailure, format!("Failed to open file: {e}")))?; @@ -78,7 +186,7 @@ impl Database { .connect() .map_err(|e| Error::new(Status::GenericFailure, format!("Failed to connect: {e}")))?; - Ok(Self::create(Some(db), io, conn, is_memory)) + Ok(Self::create(Some(db), io, conn, is_memory(&path))) } pub fn create( @@ -90,13 +198,23 @@ impl Database { Database { _db: db, io, - conn, + conn: Some(conn), is_memory, is_open: Cell::new(true), default_safe_integers: Cell::new(false), } } + fn conn(&self) -> Result> { + let Some(conn) = self.conn.as_ref() else { + return Err(napi::Error::new( + napi::Status::GenericFailure, + "connection is not set", + )); + }; + Ok(conn.clone()) + } + /// Returns whether the database is in memory-only mode. #[napi(getter)] pub fn memory(&self) -> bool { @@ -109,7 +227,7 @@ impl Database { self.is_open.get() } - /// Executes a batch of SQL statements. + /// Executes a batch of SQL statements on main thread /// /// # Arguments /// @@ -117,14 +235,23 @@ impl Database { /// /// # Returns #[napi] - pub fn batch(&self, sql: String) -> Result<()> { - self.conn.prepare_execute_batch(&sql).map_err(|e| { - Error::new( - Status::GenericFailure, - format!("Failed to execute batch: {e}"), - ) - })?; - Ok(()) + pub fn batch_sync(&self, sql: String) -> Result<()> { + batch_sync(&self.conn()?, &sql) + } + + /// Executes a batch of SQL statements outside of main thread + /// + /// # Arguments + /// + /// * `sql` - The SQL statements to execute. + /// + /// # Returns + #[napi] + pub fn batch_async(&self, sql: String) -> Result> { + Ok(AsyncTask::new(DbTask::Batch { + conn: self.conn()?.clone(), + sql, + })) } /// Prepares a statement for execution. @@ -139,14 +266,15 @@ impl Database { #[napi] pub fn prepare(&self, sql: String) -> Result { let stmt = self - .conn + .conn()? .prepare(&sql) .map_err(|e| Error::new(Status::GenericFailure, format!("{e}")))?; let column_names: Vec = (0..stmt.num_columns()) .map(|i| std::ffi::CString::new(stmt.get_column_name(i).to_string()).unwrap()) .collect(); Ok(Statement { - stmt: RefCell::new(Some(stmt)), + #[allow(clippy::arc_with_non_send_sync)] + stmt: Arc::new(RefCell::new(Some(stmt))), column_names, mode: RefCell::new(PresentationMode::Expanded), safe_integers: Cell::new(self.default_safe_integers.get()), @@ -160,7 +288,7 @@ impl Database { /// The rowid of the last row inserted. #[napi] pub fn last_insert_rowid(&self) -> Result { - Ok(self.conn.last_insert_rowid()) + Ok(self.conn()?.last_insert_rowid()) } /// Returns the number of changes made by the last statement. @@ -170,7 +298,7 @@ impl Database { /// The number of changes made by the last statement. #[napi] pub fn changes(&self) -> Result { - Ok(self.conn.changes()) + Ok(self.conn()?.changes()) } /// Returns the total number of changes made by all statements. @@ -180,7 +308,7 @@ impl Database { /// The total number of changes made by all statements. #[napi] pub fn total_changes(&self) -> Result { - Ok(self.conn.total_changes()) + Ok(self.conn()?.total_changes()) } /// Closes the database connection. @@ -189,9 +317,10 @@ impl Database { /// /// `Ok(())` if the database is closed successfully. #[napi] - pub fn close(&self) -> Result<()> { + pub fn close(&mut self) -> Result<()> { self.is_open.set(false); - // Database close is handled automatically when dropped + let _ = self._db.take().unwrap(); + let _ = self.conn.take().unwrap(); Ok(()) } @@ -225,7 +354,7 @@ impl Database { /// A prepared statement. #[napi] pub struct Statement { - stmt: RefCell>, + stmt: Arc>>, column_names: Vec, mode: RefCell, safe_integers: Cell, @@ -344,31 +473,20 @@ impl Statement { Ok(()) } - /// Step the statement and return result code: + /// Step the statement and return result code (executed on the main thread): /// 1 = Row available, 2 = Done, 3 = I/O needed #[napi] - pub fn step(&self) -> Result { - let mut stmt_ref = self.stmt.borrow_mut(); - let stmt = stmt_ref - .as_mut() - .ok_or_else(|| Error::new(Status::GenericFailure, "Statement has been finalized"))?; + pub fn step_sync(&self) -> Result { + step_sync(&self.stmt) + } - match stmt.step() { - Ok(turso_core::StepResult::Row) => Ok(STEP_ROW), - Ok(turso_core::StepResult::Done) => Ok(STEP_DONE), - Ok(turso_core::StepResult::IO) => Ok(STEP_IO), - Ok(turso_core::StepResult::Interrupt) => Err(Error::new( - Status::GenericFailure, - "Statement was interrupted", - )), - Ok(turso_core::StepResult::Busy) => { - Err(Error::new(Status::GenericFailure, "Database is busy")) - } - Err(e) => Err(Error::new( - Status::GenericFailure, - format!("Step failed: {e}"), - )), - } + /// Step the statement and return result code (executed on the background thread): + /// 1 = Row available, 2 = Done, 3 = I/O needed + #[napi] + pub fn step_async(&self) -> Result> { + Ok(AsyncTask::new(DbTask::Step { + stmt: self.stmt.clone(), + })) } /// Get the current row data according to the presentation mode @@ -543,8 +661,17 @@ fn to_js_value<'a>( turso_core::Value::Float(f) => ToNapiValue::into_unknown(*f, env), turso_core::Value::Text(s) => ToNapiValue::into_unknown(s.as_str(), env), turso_core::Value::Blob(b) => { - let buffer = Buffer::from(b.as_slice()); - ToNapiValue::into_unknown(buffer, env) + #[cfg(not(feature = "browser"))] + { + let buffer = Buffer::from(b.as_slice()); + ToNapiValue::into_unknown(buffer, env) + } + // emnapi do not support Buffer + #[cfg(feature = "browser")] + { + let buffer = Uint8Array::from(b.as_slice()); + ToNapiValue::into_unknown(buffer, env) + } } } } diff --git a/bindings/javascript/turso.wasi.cjs b/bindings/javascript/turso.wasi.cjs deleted file mode 100644 index 9aa0078af..000000000 --- a/bindings/javascript/turso.wasi.cjs +++ /dev/null @@ -1,112 +0,0 @@ -/* eslint-disable */ -/* prettier-ignore */ - -/* auto-generated by NAPI-RS */ - -const __nodeFs = require('node:fs') -const __nodePath = require('node:path') -const { WASI: __nodeWASI } = require('node:wasi') -const { Worker } = require('node:worker_threads') - -const { - createOnMessage: __wasmCreateOnMessageForFsProxy, - getDefaultContext: __emnapiGetDefaultContext, - instantiateNapiModuleSync: __emnapiInstantiateNapiModuleSync, -} = require('@napi-rs/wasm-runtime') - -const __rootDir = __nodePath.parse(process.cwd()).root - -const __wasi = new __nodeWASI({ - version: 'preview1', - env: process.env, - preopens: { - [__rootDir]: __rootDir, - } -}) - -const __emnapiContext = __emnapiGetDefaultContext() - -const __sharedMemory = new WebAssembly.Memory({ - initial: 4000, - maximum: 65536, - shared: true, -}) - -let __wasmFilePath = __nodePath.join(__dirname, 'turso.wasm32-wasi.wasm') -const __wasmDebugFilePath = __nodePath.join(__dirname, 'turso.wasm32-wasi.debug.wasm') - -if (__nodeFs.existsSync(__wasmDebugFilePath)) { - __wasmFilePath = __wasmDebugFilePath -} else if (!__nodeFs.existsSync(__wasmFilePath)) { - try { - __wasmFilePath = __nodePath.resolve('@tursodatabase/database-wasm32-wasi') - } catch { - throw new Error('Cannot find turso.wasm32-wasi.wasm file, and @tursodatabase/database-wasm32-wasi package is not installed.') - } -} - -const { instance: __napiInstance, module: __wasiModule, napiModule: __napiModule } = __emnapiInstantiateNapiModuleSync(__nodeFs.readFileSync(__wasmFilePath), { - context: __emnapiContext, - asyncWorkPoolSize: (function() { - const threadsSizeFromEnv = Number(process.env.NAPI_RS_ASYNC_WORK_POOL_SIZE ?? process.env.UV_THREADPOOL_SIZE) - // NaN > 0 is false - if (threadsSizeFromEnv > 0) { - return threadsSizeFromEnv - } else { - return 4 - } - })(), - reuseWorker: true, - wasi: __wasi, - onCreateWorker() { - const worker = new Worker(__nodePath.join(__dirname, 'wasi-worker.mjs'), { - env: process.env, - }) - worker.onmessage = ({ data }) => { - __wasmCreateOnMessageForFsProxy(__nodeFs)(data) - } - - // The main thread of Node.js waits for all the active handles before exiting. - // But Rust threads are never waited without `thread::join`. - // So here we hack the code of Node.js to prevent the workers from being referenced (active). - // According to https://github.com/nodejs/node/blob/19e0d472728c79d418b74bddff588bea70a403d0/lib/internal/worker.js#L415, - // a worker is consist of two handles: kPublicPort and kHandle. - { - const kPublicPort = Object.getOwnPropertySymbols(worker).find(s => - s.toString().includes("kPublicPort") - ); - if (kPublicPort) { - worker[kPublicPort].ref = () => {}; - } - - const kHandle = Object.getOwnPropertySymbols(worker).find(s => - s.toString().includes("kHandle") - ); - if (kHandle) { - worker[kHandle].ref = () => {}; - } - - worker.unref(); - } - return worker - }, - overwriteImports(importObject) { - importObject.env = { - ...importObject.env, - ...importObject.napi, - ...importObject.emnapi, - memory: __sharedMemory, - } - return importObject - }, - beforeInit({ instance }) { - for (const name of Object.keys(instance.exports)) { - if (name.startsWith('__napi_register__')) { - instance.exports[name]() - } - } - }, -}) -module.exports = __napiModule.exports -module.exports.Database = __napiModule.exports.Database -module.exports.Statement = __napiModule.exports.Statement diff --git a/bindings/javascript/wasi-worker-browser.mjs b/bindings/javascript/wasi-worker-browser.mjs deleted file mode 100644 index 8b1b17221..000000000 --- a/bindings/javascript/wasi-worker-browser.mjs +++ /dev/null @@ -1,32 +0,0 @@ -import { instantiateNapiModuleSync, MessageHandler, WASI } from '@napi-rs/wasm-runtime' - -const handler = new MessageHandler({ - onLoad({ wasmModule, wasmMemory }) { - const wasi = new WASI({ - print: function () { - // eslint-disable-next-line no-console - console.log.apply(console, arguments) - }, - printErr: function() { - // eslint-disable-next-line no-console - console.error.apply(console, arguments) - }, - }) - return instantiateNapiModuleSync(wasmModule, { - childThread: true, - wasi, - overwriteImports(importObject) { - importObject.env = { - ...importObject.env, - ...importObject.napi, - ...importObject.emnapi, - memory: wasmMemory, - } - }, - }) - }, -}) - -globalThis.onmessage = function (e) { - handler.handle(e) -} diff --git a/bindings/javascript/wasi-worker.mjs b/bindings/javascript/wasi-worker.mjs deleted file mode 100644 index 84b448fcc..000000000 --- a/bindings/javascript/wasi-worker.mjs +++ /dev/null @@ -1,63 +0,0 @@ -import fs from "node:fs"; -import { createRequire } from "node:module"; -import { parse } from "node:path"; -import { WASI } from "node:wasi"; -import { parentPort, Worker } from "node:worker_threads"; - -const require = createRequire(import.meta.url); - -const { instantiateNapiModuleSync, MessageHandler, getDefaultContext } = require("@napi-rs/wasm-runtime"); - -if (parentPort) { - parentPort.on("message", (data) => { - globalThis.onmessage({ data }); - }); -} - -Object.assign(globalThis, { - self: globalThis, - require, - Worker, - importScripts: function (f) { - ;(0, eval)(fs.readFileSync(f, "utf8") + "//# sourceURL=" + f); - }, - postMessage: function (msg) { - if (parentPort) { - parentPort.postMessage(msg); - } - }, -}); - -const emnapiContext = getDefaultContext(); - -const __rootDir = parse(process.cwd()).root; - -const handler = new MessageHandler({ - onLoad({ wasmModule, wasmMemory }) { - const wasi = new WASI({ - version: 'preview1', - env: process.env, - preopens: { - [__rootDir]: __rootDir, - }, - }); - - return instantiateNapiModuleSync(wasmModule, { - childThread: true, - wasi, - context: emnapiContext, - overwriteImports(importObject) { - importObject.env = { - ...importObject.env, - ...importObject.napi, - ...importObject.emnapi, - memory: wasmMemory - }; - }, - }); - }, -}); - -globalThis.onmessage = function (e) { - handler.handle(e); -}; diff --git a/bindings/javascript/yarn.lock b/bindings/javascript/yarn.lock index a0bb18897..f8d062830 100644 --- a/bindings/javascript/yarn.lock +++ b/bindings/javascript/yarn.lock @@ -5,6 +5,31 @@ __metadata: version: 8 cacheKey: 10c0 +"@babel/code-frame@npm:^7.10.4": + version: 7.27.1 + resolution: "@babel/code-frame@npm:7.27.1" + dependencies: + "@babel/helper-validator-identifier": "npm:^7.27.1" + js-tokens: "npm:^4.0.0" + picocolors: "npm:^1.1.1" + checksum: 10c0/5dd9a18baa5fce4741ba729acc3a3272c49c25cb8736c4b18e113099520e7ef7b545a4096a26d600e4416157e63e87d66db46aa3fbf0a5f2286da2705c12da00 + languageName: node + linkType: hard + +"@babel/helper-validator-identifier@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-validator-identifier@npm:7.27.1" + checksum: 10c0/c558f11c4871d526498e49d07a84752d1800bf72ac0d3dad100309a2eaba24efbf56ea59af5137ff15e3a00280ebe588560534b0e894a4750f8b1411d8f78b84 + languageName: node + linkType: hard + +"@babel/runtime@npm:^7.12.5": + version: 7.28.4 + resolution: "@babel/runtime@npm:7.28.4" + checksum: 10c0/792ce7af9750fb9b93879cc9d1db175701c4689da890e6ced242ea0207c9da411ccf16dc04e689cc01158b28d7898c40d75598f4559109f761c12ce01e959bf7 + languageName: node + linkType: hard + "@emnapi/core@npm:^1.4.5": version: 1.4.5 resolution: "@emnapi/core@npm:1.4.5" @@ -33,6 +58,188 @@ __metadata: languageName: node linkType: hard +"@esbuild/aix-ppc64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/aix-ppc64@npm:0.25.9" + conditions: os=aix & cpu=ppc64 + languageName: node + linkType: hard + +"@esbuild/android-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/android-arm64@npm:0.25.9" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/android-arm@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/android-arm@npm:0.25.9" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + +"@esbuild/android-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/android-x64@npm:0.25.9" + conditions: os=android & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/darwin-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/darwin-arm64@npm:0.25.9" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/darwin-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/darwin-x64@npm:0.25.9" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/freebsd-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/freebsd-arm64@npm:0.25.9" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/freebsd-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/freebsd-x64@npm:0.25.9" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/linux-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-arm64@npm:0.25.9" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/linux-arm@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-arm@npm:0.25.9" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@esbuild/linux-ia32@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-ia32@npm:0.25.9" + conditions: os=linux & cpu=ia32 + languageName: node + linkType: hard + +"@esbuild/linux-loong64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-loong64@npm:0.25.9" + conditions: os=linux & cpu=loong64 + languageName: node + linkType: hard + +"@esbuild/linux-mips64el@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-mips64el@npm:0.25.9" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + +"@esbuild/linux-ppc64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-ppc64@npm:0.25.9" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + +"@esbuild/linux-riscv64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-riscv64@npm:0.25.9" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + +"@esbuild/linux-s390x@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-s390x@npm:0.25.9" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + +"@esbuild/linux-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-x64@npm:0.25.9" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/netbsd-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/netbsd-arm64@npm:0.25.9" + conditions: os=netbsd & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/netbsd-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/netbsd-x64@npm:0.25.9" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/openbsd-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/openbsd-arm64@npm:0.25.9" + conditions: os=openbsd & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/openbsd-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/openbsd-x64@npm:0.25.9" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/openharmony-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/openharmony-arm64@npm:0.25.9" + conditions: os=openharmony & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/sunos-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/sunos-x64@npm:0.25.9" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/win32-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/win32-arm64@npm:0.25.9" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/win32-ia32@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/win32-ia32@npm:0.25.9" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@esbuild/win32-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/win32-x64@npm:0.25.9" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@inquirer/checkbox@npm:^4.2.0": version: 4.2.0 resolution: "@inquirer/checkbox@npm:4.2.0" @@ -281,26 +488,16 @@ __metadata: languageName: node linkType: hard -"@mapbox/node-pre-gyp@npm:^2.0.0": - version: 2.0.0 - resolution: "@mapbox/node-pre-gyp@npm:2.0.0" - dependencies: - consola: "npm:^3.2.3" - detect-libc: "npm:^2.0.0" - https-proxy-agent: "npm:^7.0.5" - node-fetch: "npm:^2.6.7" - nopt: "npm:^8.0.0" - semver: "npm:^7.5.3" - tar: "npm:^7.4.0" - bin: - node-pre-gyp: bin/node-pre-gyp - checksum: 10c0/7d874c7f6f5560a87be7207f28d9a4e53b750085a82167608fd573aab8073645e95b3608f69e244df0e1d24e90a66525aeae708aba82ca73ff668ed0ab6abda6 +"@jridgewell/sourcemap-codec@npm:^1.5.5": + version: 1.5.5 + resolution: "@jridgewell/sourcemap-codec@npm:1.5.5" + checksum: 10c0/f9e538f302b63c0ebc06eecb1dd9918dd4289ed36147a0ddce35d6ea4d7ebbda243cda7b2213b6a5e1d8087a298d5cf630fb2bd39329cdecb82017023f6081a0 languageName: node linkType: hard -"@napi-rs/cli@npm:^3.0.4": - version: 3.0.4 - resolution: "@napi-rs/cli@npm:3.0.4" +"@napi-rs/cli@npm:^3.1.5": + version: 3.1.5 + resolution: "@napi-rs/cli@npm:3.1.5" dependencies: "@inquirer/prompts": "npm:^7.4.0" "@napi-rs/cross-toolchain": "npm:^1.0.0" @@ -310,9 +507,9 @@ __metadata: colorette: "npm:^2.0.20" debug: "npm:^4.4.0" emnapi: "npm:^1.4.0" + es-toolkit: "npm:^1.39.8" find-up: "npm:^7.0.0" js-yaml: "npm:^4.1.0" - lodash-es: "npm:^4.17.21" semver: "npm:^7.7.1" typanion: "npm:^3.14.0" peerDependencies: @@ -324,9 +521,9 @@ __metadata: emnapi: optional: true bin: - napi: ./dist/cli.js - napi-raw: ./cli.mjs - checksum: 10c0/0473827231926ad6d4ffa11288fd489d1777e3586c435e5824aafe40a5e4379067726458ce8acbc2ac83ea4626fe52a3c16b0561c24cb077d2bae090153a6eb0 + napi: dist/cli.js + napi-raw: cli.mjs + checksum: 10c0/fe28bcc40f81eb4c368b4f23156f1057583de21a41400b78821829fa1aa95db8268a33fa824741c864af28a464530f05712df135a10013c6b0e4ceef4c31f324 languageName: node linkType: hard @@ -713,14 +910,14 @@ __metadata: languageName: node linkType: hard -"@napi-rs/wasm-runtime@npm:^1.0.1": - version: 1.0.1 - resolution: "@napi-rs/wasm-runtime@npm:1.0.1" +"@napi-rs/wasm-runtime@npm:^1.0.1, @napi-rs/wasm-runtime@npm:^1.0.3": + version: 1.0.3 + resolution: "@napi-rs/wasm-runtime@npm:1.0.3" dependencies: "@emnapi/core": "npm:^1.4.5" "@emnapi/runtime": "npm:^1.4.5" "@tybys/wasm-util": "npm:^0.10.0" - checksum: 10c0/3244105b75637d8d39e76782921fe46e48105bcd390db01a10dc7b596ee99af0f06b7f2b841d7632e756bd3220a5d595b9d426a5453da1ccc895900b894d098f + checksum: 10c0/7918d82477e75931b6e35bb003464382eb93e526362f81a98bf8610407a67b10f4d041931015ad48072c89db547deb7e471dfb91f4ab11ac63a24d8580297f75 languageName: node linkType: hard @@ -865,33 +1062,6 @@ __metadata: languageName: node linkType: hard -"@nodelib/fs.scandir@npm:2.1.5": - version: 2.1.5 - resolution: "@nodelib/fs.scandir@npm:2.1.5" - dependencies: - "@nodelib/fs.stat": "npm:2.0.5" - run-parallel: "npm:^1.1.9" - checksum: 10c0/732c3b6d1b1e967440e65f284bd06e5821fedf10a1bea9ed2bb75956ea1f30e08c44d3def9d6a230666574edbaf136f8cfd319c14fd1f87c66e6a44449afb2eb - languageName: node - linkType: hard - -"@nodelib/fs.stat@npm:2.0.5, @nodelib/fs.stat@npm:^2.0.2": - version: 2.0.5 - resolution: "@nodelib/fs.stat@npm:2.0.5" - checksum: 10c0/88dafe5e3e29a388b07264680dc996c17f4bda48d163a9d4f5c1112979f0ce8ec72aa7116122c350b4e7976bc5566dc3ddb579be1ceaacc727872eb4ed93926d - languageName: node - linkType: hard - -"@nodelib/fs.walk@npm:^1.2.3": - version: 1.2.8 - resolution: "@nodelib/fs.walk@npm:1.2.8" - dependencies: - "@nodelib/fs.scandir": "npm:2.1.5" - fastq: "npm:^1.6.0" - checksum: 10c0/db9de047c3bb9b51f9335a7bb46f4fcfb6829fb628318c12115fbaf7d369bfce71c15b103d1fc3b464812d936220ee9bc1c8f762d032c9f6be9acc99249095b1 - languageName: node - linkType: hard - "@npmcli/agent@npm:^3.0.0": version: 3.0.0 resolution: "@npmcli/agent@npm:3.0.0" @@ -1045,38 +1215,216 @@ __metadata: languageName: node linkType: hard -"@rollup/pluginutils@npm:^5.1.3": - version: 5.2.0 - resolution: "@rollup/pluginutils@npm:5.2.0" +"@polka/url@npm:^1.0.0-next.24": + version: 1.0.0-next.29 + resolution: "@polka/url@npm:1.0.0-next.29" + checksum: 10c0/0d58e081844095cb029d3c19a659bfefd09d5d51a2f791bc61eba7ea826f13d6ee204a8a448c2f5a855c17df07b37517373ff916dd05801063c0568ae9937684 + languageName: node + linkType: hard + +"@rollup/rollup-android-arm-eabi@npm:4.50.1": + version: 4.50.1 + resolution: "@rollup/rollup-android-arm-eabi@npm:4.50.1" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + +"@rollup/rollup-android-arm64@npm:4.50.1": + version: 4.50.1 + resolution: "@rollup/rollup-android-arm64@npm:4.50.1" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-darwin-arm64@npm:4.50.1": + version: 4.50.1 + resolution: "@rollup/rollup-darwin-arm64@npm:4.50.1" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-darwin-x64@npm:4.50.1": + version: 4.50.1 + resolution: "@rollup/rollup-darwin-x64@npm:4.50.1" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@rollup/rollup-freebsd-arm64@npm:4.50.1": + version: 4.50.1 + resolution: "@rollup/rollup-freebsd-arm64@npm:4.50.1" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-freebsd-x64@npm:4.50.1": + version: 4.50.1 + resolution: "@rollup/rollup-freebsd-x64@npm:4.50.1" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm-gnueabihf@npm:4.50.1": + version: 4.50.1 + resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.50.1" + conditions: os=linux & cpu=arm & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm-musleabihf@npm:4.50.1": + version: 4.50.1 + resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.50.1" + conditions: os=linux & cpu=arm & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm64-gnu@npm:4.50.1": + version: 4.50.1 + resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.50.1" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm64-musl@npm:4.50.1": + version: 4.50.1 + resolution: "@rollup/rollup-linux-arm64-musl@npm:4.50.1" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-linux-loongarch64-gnu@npm:4.50.1": + version: 4.50.1 + resolution: "@rollup/rollup-linux-loongarch64-gnu@npm:4.50.1" + conditions: os=linux & cpu=loong64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-ppc64-gnu@npm:4.50.1": + version: 4.50.1 + resolution: "@rollup/rollup-linux-ppc64-gnu@npm:4.50.1" + conditions: os=linux & cpu=ppc64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-riscv64-gnu@npm:4.50.1": + version: 4.50.1 + resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.50.1" + conditions: os=linux & cpu=riscv64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-riscv64-musl@npm:4.50.1": + version: 4.50.1 + resolution: "@rollup/rollup-linux-riscv64-musl@npm:4.50.1" + conditions: os=linux & cpu=riscv64 & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-linux-s390x-gnu@npm:4.50.1": + version: 4.50.1 + resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.50.1" + conditions: os=linux & cpu=s390x & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-x64-gnu@npm:4.50.1": + version: 4.50.1 + resolution: "@rollup/rollup-linux-x64-gnu@npm:4.50.1" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-x64-musl@npm:4.50.1": + version: 4.50.1 + resolution: "@rollup/rollup-linux-x64-musl@npm:4.50.1" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-openharmony-arm64@npm:4.50.1": + version: 4.50.1 + resolution: "@rollup/rollup-openharmony-arm64@npm:4.50.1" + conditions: os=openharmony & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-win32-arm64-msvc@npm:4.50.1": + version: 4.50.1 + resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.50.1" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-win32-ia32-msvc@npm:4.50.1": + version: 4.50.1 + resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.50.1" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@rollup/rollup-win32-x64-msvc@npm:4.50.1": + version: 4.50.1 + resolution: "@rollup/rollup-win32-x64-msvc@npm:4.50.1" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@testing-library/dom@npm:^10.4.0": + version: 10.4.1 + resolution: "@testing-library/dom@npm:10.4.1" dependencies: - "@types/estree": "npm:^1.0.0" - estree-walker: "npm:^2.0.2" - picomatch: "npm:^4.0.2" + "@babel/code-frame": "npm:^7.10.4" + "@babel/runtime": "npm:^7.12.5" + "@types/aria-query": "npm:^5.0.1" + aria-query: "npm:5.3.0" + dom-accessibility-api: "npm:^0.5.9" + lz-string: "npm:^1.5.0" + picocolors: "npm:1.1.1" + pretty-format: "npm:^27.0.2" + checksum: 10c0/19ce048012d395ad0468b0dbcc4d0911f6f9e39464d7a8464a587b29707eed5482000dad728f5acc4ed314d2f4d54f34982999a114d2404f36d048278db815b1 + languageName: node + linkType: hard + +"@testing-library/user-event@npm:^14.6.1": + version: 14.6.1 + resolution: "@testing-library/user-event@npm:14.6.1" peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - checksum: 10c0/794890d512751451bcc06aa112366ef47ea8f9125dac49b1abf72ff8b079518b09359de9c60a013b33266541634e765ae61839c749fae0edb59a463418665c55 + "@testing-library/dom": ">=7.21.4" + checksum: 10c0/75fea130a52bf320d35d46ed54f3eec77e71a56911b8b69a3fe29497b0b9947b2dc80d30f04054ad4ce7f577856ae3e5397ea7dff0ef14944d3909784c7a93fe languageName: node linkType: hard -"@sindresorhus/merge-streams@npm:^2.1.0": - version: 2.3.0 - resolution: "@sindresorhus/merge-streams@npm:2.3.0" - checksum: 10c0/69ee906f3125fb2c6bb6ec5cdd84e8827d93b49b3892bce8b62267116cc7e197b5cccf20c160a1d32c26014ecd14470a72a5e3ee37a58f1d6dadc0db1ccf3894 - languageName: node - linkType: hard - -"@tursodatabase/database@workspace:.": +"@tursodatabase/database-browser@workspace:packages/browser": version: 0.0.0-use.local - resolution: "@tursodatabase/database@workspace:." + resolution: "@tursodatabase/database-browser@workspace:packages/browser" dependencies: - "@napi-rs/cli": "npm:^3.0.4" - "@napi-rs/wasm-runtime": "npm:^1.0.1" - ava: "npm:^6.0.1" - better-sqlite3: "npm:^11.9.1" + "@napi-rs/cli": "npm:^3.1.5" + "@napi-rs/wasm-runtime": "npm:^1.0.3" + "@tursodatabase/database-common": "npm:^0.1.5-pre.5" + "@vitest/browser": "npm:^3.2.4" + playwright: "npm:^1.55.0" typescript: "npm:^5.9.2" + vitest: "npm:^3.2.4" + languageName: unknown + linkType: soft + +"@tursodatabase/database-common@npm:^0.1.5-pre.5, @tursodatabase/database-common@workspace:packages/common": + version: 0.0.0-use.local + resolution: "@tursodatabase/database-common@workspace:packages/common" + dependencies: + typescript: "npm:^5.9.2" + languageName: unknown + linkType: soft + +"@tursodatabase/database@workspace:packages/native": + version: 0.0.0-use.local + resolution: "@tursodatabase/database@workspace:packages/native" + dependencies: + "@napi-rs/cli": "npm:^3.1.5" + "@tursodatabase/database-common": "npm:^0.1.5-pre.5" + "@types/node": "npm:^24.3.1" + typescript: "npm:^5.9.2" + vitest: "npm:^3.2.4" languageName: unknown linkType: soft @@ -1089,32 +1437,152 @@ __metadata: languageName: node linkType: hard -"@types/estree@npm:^1.0.0": +"@types/aria-query@npm:^5.0.1": + version: 5.0.4 + resolution: "@types/aria-query@npm:5.0.4" + checksum: 10c0/dc667bc6a3acc7bba2bccf8c23d56cb1f2f4defaa704cfef595437107efaa972d3b3db9ec1d66bc2711bfc35086821edd32c302bffab36f2e79b97f312069f08 + languageName: node + linkType: hard + +"@types/chai@npm:^5.2.2": + version: 5.2.2 + resolution: "@types/chai@npm:5.2.2" + dependencies: + "@types/deep-eql": "npm:*" + checksum: 10c0/49282bf0e8246800ebb36f17256f97bd3a8c4fb31f92ad3c0eaa7623518d7e87f1eaad4ad206960fcaf7175854bdff4cb167e4fe96811e0081b4ada83dd533ec + languageName: node + linkType: hard + +"@types/deep-eql@npm:*": + version: 4.0.2 + resolution: "@types/deep-eql@npm:4.0.2" + checksum: 10c0/bf3f811843117900d7084b9d0c852da9a044d12eb40e6de73b552598a6843c21291a8a381b0532644574beecd5e3491c5ff3a0365ab86b15d59862c025384844 + languageName: node + linkType: hard + +"@types/estree@npm:1.0.8, @types/estree@npm:^1.0.0": version: 1.0.8 resolution: "@types/estree@npm:1.0.8" checksum: 10c0/39d34d1afaa338ab9763f37ad6066e3f349444f9052b9676a7cc0252ef9485a41c6d81c9c4e0d26e9077993354edf25efc853f3224dd4b447175ef62bdcc86a5 languageName: node linkType: hard -"@vercel/nft@npm:^0.29.4": - version: 0.29.4 - resolution: "@vercel/nft@npm:0.29.4" +"@types/node@npm:^24.3.1": + version: 24.3.1 + resolution: "@types/node@npm:24.3.1" dependencies: - "@mapbox/node-pre-gyp": "npm:^2.0.0" - "@rollup/pluginutils": "npm:^5.1.3" - acorn: "npm:^8.6.0" - acorn-import-attributes: "npm:^1.9.5" - async-sema: "npm:^3.1.1" - bindings: "npm:^1.4.0" - estree-walker: "npm:2.0.2" - glob: "npm:^10.4.5" - graceful-fs: "npm:^4.2.9" - node-gyp-build: "npm:^4.2.2" - picomatch: "npm:^4.0.2" - resolve-from: "npm:^5.0.0" - bin: - nft: out/cli.js - checksum: 10c0/84ba32c685f9d7c2c849b1e8c963d3b7eb09d122e666143ed97c3776f5b04a4745605e1d29fd81383f72b1d1c0d7d58e39f06dc92f021b5de079dfa4e8523574 + undici-types: "npm:~7.10.0" + checksum: 10c0/99b86fc32294fcd61136ca1f771026443a1e370e9f284f75e243b29299dd878e18c193deba1ce29a374932db4e30eb80826e1049b9aad02d36f5c30b94b6f928 + languageName: node + linkType: hard + +"@vitest/browser@npm:^3.2.4": + version: 3.2.4 + resolution: "@vitest/browser@npm:3.2.4" + dependencies: + "@testing-library/dom": "npm:^10.4.0" + "@testing-library/user-event": "npm:^14.6.1" + "@vitest/mocker": "npm:3.2.4" + "@vitest/utils": "npm:3.2.4" + magic-string: "npm:^0.30.17" + sirv: "npm:^3.0.1" + tinyrainbow: "npm:^2.0.0" + ws: "npm:^8.18.2" + peerDependencies: + playwright: "*" + vitest: 3.2.4 + webdriverio: ^7.0.0 || ^8.0.0 || ^9.0.0 + peerDependenciesMeta: + playwright: + optional: true + safaridriver: + optional: true + webdriverio: + optional: true + checksum: 10c0/0db39daad675aad187eff27d5a7f17a9f533d7abc7476ee1a0b83a9c62a7227b24395f4814e034ecb2ebe39f1a2dec0a8c6a7f79b8d5680c3ac79e408727d742 + languageName: node + linkType: hard + +"@vitest/expect@npm:3.2.4": + version: 3.2.4 + resolution: "@vitest/expect@npm:3.2.4" + dependencies: + "@types/chai": "npm:^5.2.2" + "@vitest/spy": "npm:3.2.4" + "@vitest/utils": "npm:3.2.4" + chai: "npm:^5.2.0" + tinyrainbow: "npm:^2.0.0" + checksum: 10c0/7586104e3fd31dbe1e6ecaafb9a70131e4197dce2940f727b6a84131eee3decac7b10f9c7c72fa5edbdb68b6f854353bd4c0fa84779e274207fb7379563b10db + languageName: node + linkType: hard + +"@vitest/mocker@npm:3.2.4": + version: 3.2.4 + resolution: "@vitest/mocker@npm:3.2.4" + dependencies: + "@vitest/spy": "npm:3.2.4" + estree-walker: "npm:^3.0.3" + magic-string: "npm:^0.30.17" + peerDependencies: + msw: ^2.4.9 + vite: ^5.0.0 || ^6.0.0 || ^7.0.0-0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + checksum: 10c0/f7a4aea19bbbf8f15905847ee9143b6298b2c110f8b64789224cb0ffdc2e96f9802876aa2ca83f1ec1b6e1ff45e822abb34f0054c24d57b29ab18add06536ccd + languageName: node + linkType: hard + +"@vitest/pretty-format@npm:3.2.4, @vitest/pretty-format@npm:^3.2.4": + version: 3.2.4 + resolution: "@vitest/pretty-format@npm:3.2.4" + dependencies: + tinyrainbow: "npm:^2.0.0" + checksum: 10c0/5ad7d4278e067390d7d633e307fee8103958806a419ca380aec0e33fae71b44a64415f7a9b4bc11635d3c13d4a9186111c581d3cef9c65cc317e68f077456887 + languageName: node + linkType: hard + +"@vitest/runner@npm:3.2.4": + version: 3.2.4 + resolution: "@vitest/runner@npm:3.2.4" + dependencies: + "@vitest/utils": "npm:3.2.4" + pathe: "npm:^2.0.3" + strip-literal: "npm:^3.0.0" + checksum: 10c0/e8be51666c72b3668ae3ea348b0196656a4a5adb836cb5e270720885d9517421815b0d6c98bfdf1795ed02b994b7bfb2b21566ee356a40021f5bf4f6ed4e418a + languageName: node + linkType: hard + +"@vitest/snapshot@npm:3.2.4": + version: 3.2.4 + resolution: "@vitest/snapshot@npm:3.2.4" + dependencies: + "@vitest/pretty-format": "npm:3.2.4" + magic-string: "npm:^0.30.17" + pathe: "npm:^2.0.3" + checksum: 10c0/f8301a3d7d1559fd3d59ed51176dd52e1ed5c2d23aa6d8d6aa18787ef46e295056bc726a021698d8454c16ed825ecba163362f42fa90258bb4a98cfd2c9424fc + languageName: node + linkType: hard + +"@vitest/spy@npm:3.2.4": + version: 3.2.4 + resolution: "@vitest/spy@npm:3.2.4" + dependencies: + tinyspy: "npm:^4.0.3" + checksum: 10c0/6ebf0b4697dc238476d6b6a60c76ba9eb1dd8167a307e30f08f64149612fd50227682b876420e4c2e09a76334e73f72e3ebf0e350714dc22474258292e202024 + languageName: node + linkType: hard + +"@vitest/utils@npm:3.2.4": + version: 3.2.4 + resolution: "@vitest/utils@npm:3.2.4" + dependencies: + "@vitest/pretty-format": "npm:3.2.4" + loupe: "npm:^3.1.4" + tinyrainbow: "npm:^2.0.0" + checksum: 10c0/024a9b8c8bcc12cf40183c246c244b52ecff861c6deb3477cbf487ac8781ad44c68a9c5fd69f8c1361878e55b97c10d99d511f2597f1f7244b5e5101d028ba64 languageName: node linkType: hard @@ -1125,33 +1593,6 @@ __metadata: languageName: node linkType: hard -"acorn-import-attributes@npm:^1.9.5": - version: 1.9.5 - resolution: "acorn-import-attributes@npm:1.9.5" - peerDependencies: - acorn: ^8 - checksum: 10c0/5926eaaead2326d5a86f322ff1b617b0f698aa61dc719a5baa0e9d955c9885cc71febac3fb5bacff71bbf2c4f9c12db2056883c68c53eb962c048b952e1e013d - languageName: node - linkType: hard - -"acorn-walk@npm:^8.3.4": - version: 8.3.4 - resolution: "acorn-walk@npm:8.3.4" - dependencies: - acorn: "npm:^8.11.0" - checksum: 10c0/76537ac5fb2c37a64560feaf3342023dadc086c46da57da363e64c6148dc21b57d49ace26f949e225063acb6fb441eabffd89f7a3066de5ad37ab3e328927c62 - languageName: node - linkType: hard - -"acorn@npm:^8.11.0, acorn@npm:^8.15.0, acorn@npm:^8.6.0": - version: 8.15.0 - resolution: "acorn@npm:8.15.0" - bin: - acorn: bin/acorn - checksum: 10c0/dec73ff59b7d6628a01eebaece7f2bdb8bb62b9b5926dcad0f8931f2b8b79c2be21f6c68ac095592adb5adb15831a3635d9343e6a91d028bbe85d564875ec3ec - languageName: node - linkType: hard - "agent-base@npm:^7.1.0, agent-base@npm:^7.1.2": version: 7.1.4 resolution: "agent-base@npm:7.1.4" @@ -1176,9 +1617,9 @@ __metadata: linkType: hard "ansi-regex@npm:^6.0.1": - version: 6.1.0 - resolution: "ansi-regex@npm:6.1.0" - checksum: 10c0/a91daeddd54746338478eef88af3439a7edf30f8e23196e2d6ed182da9add559c601266dbef01c2efa46a958ad6f1f8b176799657616c702b5b02e799e7fd8dc + version: 6.2.2 + resolution: "ansi-regex@npm:6.2.2" + checksum: 10c0/05d4acb1d2f59ab2cf4b794339c7b168890d44dda4bf0ce01152a8da0213aca207802f930442ce8cd22d7a92f44907664aac6508904e75e038fa944d2601b30f languageName: node linkType: hard @@ -1191,19 +1632,17 @@ __metadata: languageName: node linkType: hard -"ansi-styles@npm:^6.0.0, ansi-styles@npm:^6.1.0, ansi-styles@npm:^6.2.1": - version: 6.2.1 - resolution: "ansi-styles@npm:6.2.1" - checksum: 10c0/5d1ec38c123984bcedd996eac680d548f31828bd679a66db2bdf11844634dde55fec3efa9c6bb1d89056a5e79c1ac540c4c784d592ea1d25028a92227d2f2d5c +"ansi-styles@npm:^5.0.0": + version: 5.2.0 + resolution: "ansi-styles@npm:5.2.0" + checksum: 10c0/9c4ca80eb3c2fb7b33841c210d2f20807f40865d27008d7c3f707b7f95cab7d67462a565e2388ac3285b71cb3d9bb2173de8da37c57692a362885ec34d6e27df languageName: node linkType: hard -"argparse@npm:^1.0.7": - version: 1.0.10 - resolution: "argparse@npm:1.0.10" - dependencies: - sprintf-js: "npm:~1.0.2" - checksum: 10c0/b2972c5c23c63df66bca144dbc65d180efa74f25f8fd9b7d9a0a6c88ae839db32df3d54770dcb6460cf840d232b60695d1a6b1053f599d84e73f7437087712de +"ansi-styles@npm:^6.1.0": + version: 6.2.3 + resolution: "ansi-styles@npm:6.2.3" + checksum: 10c0/23b8a4ce14e18fb854693b95351e286b771d23d8844057ed2e7d083cd3e708376c3323707ec6a24365f7d7eda3ca00327fe04092e29e551499ec4c8b7bfac868 languageName: node linkType: hard @@ -1214,86 +1653,19 @@ __metadata: languageName: node linkType: hard -"array-find-index@npm:^1.0.1": - version: 1.0.2 - resolution: "array-find-index@npm:1.0.2" - checksum: 10c0/86b9485c74ddd324feab807e10a6de3f9c1683856267236fac4bb4d4667ada6463e106db3f6c540ae6b720e0442b590ec701d13676df4c6af30ebf4da09b4f57 - languageName: node - linkType: hard - -"arrgv@npm:^1.0.2": - version: 1.0.2 - resolution: "arrgv@npm:1.0.2" - checksum: 10c0/7e6e782e6b749923ac7cbc4048ef6fe0844c4a59bfc8932fcd4c44566ba25eed46501f94dd7cf3c7297da88f3f599ca056bfb77d0c2484aebc92f04239f69124 - languageName: node - linkType: hard - -"arrify@npm:^3.0.0": - version: 3.0.0 - resolution: "arrify@npm:3.0.0" - checksum: 10c0/2e26601b8486f29780f1f70f7ac05a226755814c2a3ab42e196748f650af1dc310cd575a11dd4b9841c70fd7460b2dd2b8fe6fb7a3375878e2660706efafa58e - languageName: node - linkType: hard - -"async-sema@npm:^3.1.1": - version: 3.1.1 - resolution: "async-sema@npm:3.1.1" - checksum: 10c0/a16da9f7f2dbdd00a969bf264b7ad331b59df3eac2b38f529b881c5cc8662594e68ed096d927ec2aabdc13454379cdc6d677bcdb0a3d2db338fb4be17957832b - languageName: node - linkType: hard - -"ava@npm:^6.0.1": - version: 6.4.1 - resolution: "ava@npm:6.4.1" +"aria-query@npm:5.3.0": + version: 5.3.0 + resolution: "aria-query@npm:5.3.0" dependencies: - "@vercel/nft": "npm:^0.29.4" - acorn: "npm:^8.15.0" - acorn-walk: "npm:^8.3.4" - ansi-styles: "npm:^6.2.1" - arrgv: "npm:^1.0.2" - arrify: "npm:^3.0.0" - callsites: "npm:^4.2.0" - cbor: "npm:^10.0.9" - chalk: "npm:^5.4.1" - chunkd: "npm:^2.0.1" - ci-info: "npm:^4.3.0" - ci-parallel-vars: "npm:^1.0.1" - cli-truncate: "npm:^4.0.0" - code-excerpt: "npm:^4.0.0" - common-path-prefix: "npm:^3.0.0" - concordance: "npm:^5.0.4" - currently-unhandled: "npm:^0.4.1" - debug: "npm:^4.4.1" - emittery: "npm:^1.2.0" - figures: "npm:^6.1.0" - globby: "npm:^14.1.0" - ignore-by-default: "npm:^2.1.0" - indent-string: "npm:^5.0.0" - is-plain-object: "npm:^5.0.0" - is-promise: "npm:^4.0.0" - matcher: "npm:^5.0.0" - memoize: "npm:^10.1.0" - ms: "npm:^2.1.3" - p-map: "npm:^7.0.3" - package-config: "npm:^5.0.0" - picomatch: "npm:^4.0.2" - plur: "npm:^5.1.0" - pretty-ms: "npm:^9.2.0" - resolve-cwd: "npm:^3.0.0" - stack-utils: "npm:^2.0.6" - strip-ansi: "npm:^7.1.0" - supertap: "npm:^3.0.1" - temp-dir: "npm:^3.0.0" - write-file-atomic: "npm:^6.0.0" - yargs: "npm:^17.7.2" - peerDependencies: - "@ava/typescript": "*" - peerDependenciesMeta: - "@ava/typescript": - optional: true - bin: - ava: entrypoints/cli.mjs - checksum: 10c0/21972df1031ef46533ea1b7daa132a5fc66841c8a221b6901163d12d2a1cac39bfd8a6d3459da7eb9344fa90fc02f237f2fe2aac8785d04bf5894fa43625be28 + dequal: "npm:^2.0.3" + checksum: 10c0/2bff0d4eba5852a9dd578ecf47eaef0e82cc52569b48469b0aac2db5145db0b17b7a58d9e01237706d1e14b7a1b0ac9b78e9c97027ad97679dd8f91b85da1469 + languageName: node + linkType: hard + +"assertion-error@npm:^2.0.1": + version: 2.0.1 + resolution: "assertion-error@npm:2.0.1" + checksum: 10c0/bbbcb117ac6480138f8c93cf7f535614282dea9dc828f540cdece85e3c665e8f78958b96afac52f29ff883c72638e6a87d469ecc9fe5bc902df03ed24a55dba8 languageName: node linkType: hard @@ -1304,13 +1676,6 @@ __metadata: languageName: node linkType: hard -"base64-js@npm:^1.3.1": - version: 1.5.1 - resolution: "base64-js@npm:1.5.1" - checksum: 10c0/f23823513b63173a001030fae4f2dabe283b99a9d324ade3ad3d148e218134676f1ee8568c877cd79ec1c53158dcf2d2ba527a97c606618928ba99dd930102bf - languageName: node - linkType: hard - "before-after-hook@npm:^4.0.0": version: 4.0.0 resolution: "before-after-hook@npm:4.0.0" @@ -1318,44 +1683,6 @@ __metadata: languageName: node linkType: hard -"better-sqlite3@npm:^11.9.1": - version: 11.10.0 - resolution: "better-sqlite3@npm:11.10.0" - dependencies: - bindings: "npm:^1.5.0" - node-gyp: "npm:latest" - prebuild-install: "npm:^7.1.1" - checksum: 10c0/1fffbf9e5fc9d24847a3ecf09491bceab1c294b46ba41df1c449dc20b6f5c5d9d94ff24becd0b1632ee282bd21278b7fea53a5a6215bb99209ded0ae05eda3b0 - languageName: node - linkType: hard - -"bindings@npm:^1.4.0, bindings@npm:^1.5.0": - version: 1.5.0 - resolution: "bindings@npm:1.5.0" - dependencies: - file-uri-to-path: "npm:1.0.0" - checksum: 10c0/3dab2491b4bb24124252a91e656803eac24292473e56554e35bbfe3cc1875332cfa77600c3bac7564049dc95075bf6fcc63a4609920ff2d64d0fe405fcf0d4ba - languageName: node - linkType: hard - -"bl@npm:^4.0.3": - version: 4.1.0 - resolution: "bl@npm:4.1.0" - dependencies: - buffer: "npm:^5.5.0" - inherits: "npm:^2.0.4" - readable-stream: "npm:^3.4.0" - checksum: 10c0/02847e1d2cb089c9dc6958add42e3cdeaf07d13f575973963335ac0fdece563a50ac770ac4c8fa06492d2dd276f6cc3b7f08c7cd9c7a7ad0f8d388b2a28def5f - languageName: node - linkType: hard - -"blueimp-md5@npm:^2.10.0": - version: 2.19.0 - resolution: "blueimp-md5@npm:2.19.0" - checksum: 10c0/85d04343537dd99a288c62450341dcce7380d3454c81f8e5a971ddd80307d6f9ef51b5b92ad7d48aaaa92fd6d3a1f6b2f4fada068faae646887f7bfabc17a346 - languageName: node - linkType: hard - "brace-expansion@npm:^2.0.1": version: 2.0.2 resolution: "brace-expansion@npm:2.0.2" @@ -1365,22 +1692,10 @@ __metadata: languageName: node linkType: hard -"braces@npm:^3.0.3": - version: 3.0.3 - resolution: "braces@npm:3.0.3" - dependencies: - fill-range: "npm:^7.1.1" - checksum: 10c0/7c6dfd30c338d2997ba77500539227b9d1f85e388a5f43220865201e407e076783d0881f2d297b9f80951b4c957fcf0b51c1d2d24227631643c3f7c284b0aa04 - languageName: node - linkType: hard - -"buffer@npm:^5.5.0": - version: 5.7.1 - resolution: "buffer@npm:5.7.1" - dependencies: - base64-js: "npm:^1.3.1" - ieee754: "npm:^1.1.13" - checksum: 10c0/27cac81cff434ed2876058d72e7c4789d11ff1120ef32c9de48f59eab58179b66710c488987d295ae89a228f835fc66d088652dffeb8e3ba8659f80eb091d55e +"cac@npm:^6.7.14": + version: 6.7.14 + resolution: "cac@npm:6.7.14" + checksum: 10c0/4ee06aaa7bab8981f0d54e5f5f9d4adcd64058e9697563ce336d8a3878ed018ee18ebe5359b2430eceae87e0758e62ea2019c3f52ae6e211b1bd2e133856cd10 languageName: node linkType: hard @@ -1404,26 +1719,16 @@ __metadata: languageName: node linkType: hard -"callsites@npm:^4.2.0": - version: 4.2.0 - resolution: "callsites@npm:4.2.0" - checksum: 10c0/8f7e269ec09fc0946bb22d838a8bc7932e1909ab4a833b964749f4d0e8bdeaa1f253287c4f911f61781f09620b6925ccd19a5ea4897489c4e59442c660c312a3 - languageName: node - linkType: hard - -"cbor@npm:^10.0.9": - version: 10.0.9 - resolution: "cbor@npm:10.0.9" +"chai@npm:^5.2.0": + version: 5.3.3 + resolution: "chai@npm:5.3.3" dependencies: - nofilter: "npm:^3.0.2" - checksum: 10c0/49b59036c340ab0c6f4fa39aaf37ed6cb2bec6d54ec27b45a03f5df0fcd5767594b0abb5cbf44d69bdd8593d6a2e131c3e7017c511bacf05f5aa4ff2af82d07d - languageName: node - linkType: hard - -"chalk@npm:^5.4.1": - version: 5.4.1 - resolution: "chalk@npm:5.4.1" - checksum: 10c0/b23e88132c702f4855ca6d25cb5538b1114343e41472d5263ee8a37cccfccd9c4216d111e1097c6a27830407a1dc81fecdf2a56f2c63033d4dbbd88c10b0dcef + assertion-error: "npm:^2.0.1" + check-error: "npm:^2.1.1" + deep-eql: "npm:^5.0.1" + loupe: "npm:^3.1.0" + pathval: "npm:^2.0.0" + checksum: 10c0/b360fd4d38861622e5010c2f709736988b05c7f31042305fa3f4e9911f6adb80ccfb4e302068bf8ed10e835c2e2520cba0f5edc13d878b886987e5aa62483f53 languageName: node linkType: hard @@ -1434,10 +1739,10 @@ __metadata: languageName: node linkType: hard -"chownr@npm:^1.1.1": - version: 1.1.4 - resolution: "chownr@npm:1.1.4" - checksum: 10c0/ed57952a84cc0c802af900cf7136de643d3aba2eecb59d29344bc2f3f9bf703a301b9d84cdc71f82c3ffc9ccde831b0d92f5b45f91727d6c9da62f23aef9d9db +"check-error@npm:^2.1.1": + version: 2.1.1 + resolution: "check-error@npm:2.1.1" + checksum: 10c0/979f13eccab306cf1785fa10941a590b4e7ea9916ea2a4f8c87f0316fc3eab07eabefb6e587424ef0f88cbcd3805791f172ea739863ca3d7ce2afc54641c7f0e languageName: node linkType: hard @@ -1448,37 +1753,6 @@ __metadata: languageName: node linkType: hard -"chunkd@npm:^2.0.1": - version: 2.0.1 - resolution: "chunkd@npm:2.0.1" - checksum: 10c0/4e0c5aac6048ecedfa4cd0a5f6c4f010c70a7b7645aeca7bfeb47cb0733c3463054f0ced3f2667b2e0e67edd75d68a8e05481b01115ba3f8a952a93026254504 - languageName: node - linkType: hard - -"ci-info@npm:^4.3.0": - version: 4.3.0 - resolution: "ci-info@npm:4.3.0" - checksum: 10c0/60d3dfe95d75c01454ec1cfd5108617dd598a28a2a3e148bd7e1523c1c208b5f5a3007cafcbe293e6fd0a5a310cc32217c5dc54743eeabc0a2bec80072fc055c - languageName: node - linkType: hard - -"ci-parallel-vars@npm:^1.0.1": - version: 1.0.1 - resolution: "ci-parallel-vars@npm:1.0.1" - checksum: 10c0/80952f699cbbc146092b077b4f3e28d085620eb4e6be37f069b4dbb3db0ee70e8eec3beef4ebe70ff60631e9fc743b9d0869678489f167442cac08b260e5ac08 - languageName: node - linkType: hard - -"cli-truncate@npm:^4.0.0": - version: 4.0.0 - resolution: "cli-truncate@npm:4.0.0" - dependencies: - slice-ansi: "npm:^5.0.0" - string-width: "npm:^7.0.0" - checksum: 10c0/d7f0b73e3d9b88cb496e6c086df7410b541b56a43d18ade6a573c9c18bd001b1c3fba1ad578f741a4218fdc794d042385f8ac02c25e1c295a2d8b9f3cb86eb4c - languageName: node - linkType: hard - "cli-width@npm:^4.1.0": version: 4.1.0 resolution: "cli-width@npm:4.1.0" @@ -1497,26 +1771,6 @@ __metadata: languageName: node linkType: hard -"cliui@npm:^8.0.1": - version: 8.0.1 - resolution: "cliui@npm:8.0.1" - dependencies: - string-width: "npm:^4.2.0" - strip-ansi: "npm:^6.0.1" - wrap-ansi: "npm:^7.0.0" - checksum: 10c0/4bda0f09c340cbb6dfdc1ed508b3ca080f12992c18d68c6be4d9cf51756033d5266e61ec57529e610dacbf4da1c634423b0c1b11037709cc6b09045cbd815df5 - languageName: node - linkType: hard - -"code-excerpt@npm:^4.0.0": - version: 4.0.0 - resolution: "code-excerpt@npm:4.0.0" - dependencies: - convert-to-spaces: "npm:^2.0.1" - checksum: 10c0/b6c5a06e039cecd2ab6a0e10ee0831de8362107d1f298ca3558b5f9004cb8e0260b02dd6c07f57b9a0e346c76864d2873311ee1989809fdeb05bd5fbbadde773 - languageName: node - linkType: hard - "color-convert@npm:^2.0.1": version: 2.0.1 resolution: "color-convert@npm:2.0.1" @@ -1540,43 +1794,6 @@ __metadata: languageName: node linkType: hard -"common-path-prefix@npm:^3.0.0": - version: 3.0.0 - resolution: "common-path-prefix@npm:3.0.0" - checksum: 10c0/c4a74294e1b1570f4a8ab435285d185a03976c323caa16359053e749db4fde44e3e6586c29cd051100335e11895767cbbd27ea389108e327d62f38daf4548fdb - languageName: node - linkType: hard - -"concordance@npm:^5.0.4": - version: 5.0.4 - resolution: "concordance@npm:5.0.4" - dependencies: - date-time: "npm:^3.1.0" - esutils: "npm:^2.0.3" - fast-diff: "npm:^1.2.0" - js-string-escape: "npm:^1.0.1" - lodash: "npm:^4.17.15" - md5-hex: "npm:^3.0.1" - semver: "npm:^7.3.2" - well-known-symbols: "npm:^2.0.0" - checksum: 10c0/59b440f330df3a7c9aa148ba588b3e99aed86acab225b4f01ffcea34ace4cf11f817e31153254e8f38ed48508998dad40b9106951a743c334d751f7ab21afb8a - languageName: node - linkType: hard - -"consola@npm:^3.2.3": - version: 3.4.2 - resolution: "consola@npm:3.4.2" - checksum: 10c0/7cebe57ecf646ba74b300bcce23bff43034ed6fbec9f7e39c27cee1dc00df8a21cd336b466ad32e304ea70fba04ec9e890c200270de9a526ce021ba8a7e4c11a - languageName: node - linkType: hard - -"convert-to-spaces@npm:^2.0.1": - version: 2.0.1 - resolution: "convert-to-spaces@npm:2.0.1" - checksum: 10c0/d90aa0e3b6a27f9d5265a8d32def3c5c855b3e823a9db1f26d772f8146d6b91020a2fdfd905ce8048a73fad3aaf836fef8188c67602c374405e2ae8396c4ac46 - languageName: node - linkType: hard - "cross-spawn@npm:^7.0.6": version: 7.0.6 resolution: "cross-spawn@npm:7.0.6" @@ -1588,24 +1805,6 @@ __metadata: languageName: node linkType: hard -"currently-unhandled@npm:^0.4.1": - version: 0.4.1 - resolution: "currently-unhandled@npm:0.4.1" - dependencies: - array-find-index: "npm:^1.0.1" - checksum: 10c0/32d197689ec32f035910202c1abb0dc6424dce01d7b51779c685119b380d98535c110ffff67a262fc7e367612a7dfd30d3d3055f9a6634b5a9dd1302de7ef11c - languageName: node - linkType: hard - -"date-time@npm:^3.1.0": - version: 3.1.0 - resolution: "date-time@npm:3.1.0" - dependencies: - time-zone: "npm:^1.0.0" - checksum: 10c0/aa3e2e930d74b0b9e90f69de7a16d3376e30f21f1f4ce9a2311d8fec32d760e776efea752dafad0ce188187265235229013036202be053fc2d7979813bfb6ded - languageName: node - linkType: hard - "debug@npm:4, debug@npm:^4.3.4, debug@npm:^4.4.0, debug@npm:^4.4.1": version: 4.4.1 resolution: "debug@npm:4.4.1" @@ -1618,26 +1817,24 @@ __metadata: languageName: node linkType: hard -"decompress-response@npm:^6.0.0": - version: 6.0.0 - resolution: "decompress-response@npm:6.0.0" - dependencies: - mimic-response: "npm:^3.1.0" - checksum: 10c0/bd89d23141b96d80577e70c54fb226b2f40e74a6817652b80a116d7befb8758261ad073a8895648a29cc0a5947021ab66705cb542fa9c143c82022b27c5b175e +"deep-eql@npm:^5.0.1": + version: 5.0.2 + resolution: "deep-eql@npm:5.0.2" + checksum: 10c0/7102cf3b7bb719c6b9c0db2e19bf0aa9318d141581befe8c7ce8ccd39af9eaa4346e5e05adef7f9bd7015da0f13a3a25dcfe306ef79dc8668aedbecb658dd247 languageName: node linkType: hard -"deep-extend@npm:^0.6.0": - version: 0.6.0 - resolution: "deep-extend@npm:0.6.0" - checksum: 10c0/1c6b0abcdb901e13a44c7d699116d3d4279fdb261983122a3783e7273844d5f2537dc2e1c454a23fcf645917f93fbf8d07101c1d03c015a87faa662755212566 +"dequal@npm:^2.0.3": + version: 2.0.3 + resolution: "dequal@npm:2.0.3" + checksum: 10c0/f98860cdf58b64991ae10205137c0e97d384c3a4edc7f807603887b7c4b850af1224a33d88012009f150861cbee4fa2d322c4cc04b9313bee312e47f6ecaa888 languageName: node linkType: hard -"detect-libc@npm:^2.0.0": - version: 2.0.4 - resolution: "detect-libc@npm:2.0.4" - checksum: 10c0/c15541f836eba4b1f521e4eecc28eefefdbc10a94d3b8cb4c507689f332cc111babb95deda66f2de050b22122113189986d5190be97d51b5a2b23b938415e67c +"dom-accessibility-api@npm:^0.5.9": + version: 0.5.16 + resolution: "dom-accessibility-api@npm:0.5.16" + checksum: 10c0/b2c2eda4fae568977cdac27a9f0c001edf4f95a6a6191dfa611e3721db2478d1badc01db5bb4fa8a848aeee13e442a6c2a4386d65ec65a1436f24715a2f8d053 languageName: node linkType: hard @@ -1648,13 +1845,6 @@ __metadata: languageName: node linkType: hard -"emittery@npm:^1.2.0": - version: 1.2.0 - resolution: "emittery@npm:1.2.0" - checksum: 10c0/3b16d67b2cbbc19d44fa124684039956dc94c376cefa8c7b29f4c934d9d370e6819f642cddaa343b83b1fc03fda554a1498e12f5861caf9d6f6394ff4b6e808a - languageName: node - linkType: hard - "emnapi@npm:^1.4.0": version: 1.4.5 resolution: "emnapi@npm:1.4.5" @@ -1667,13 +1857,6 @@ __metadata: languageName: node linkType: hard -"emoji-regex@npm:^10.3.0": - version: 10.4.0 - resolution: "emoji-regex@npm:10.4.0" - checksum: 10c0/a3fcedfc58bfcce21a05a5f36a529d81e88d602100145fcca3dc6f795e3c8acc4fc18fe773fbf9b6d6e9371205edb3afa2668ec3473fa2aa7fd47d2a9d46482d - languageName: node - linkType: hard - "emoji-regex@npm:^8.0.0": version: 8.0.0 resolution: "emoji-regex@npm:8.0.0" @@ -1697,15 +1880,6 @@ __metadata: languageName: node linkType: hard -"end-of-stream@npm:^1.1.0, end-of-stream@npm:^1.4.1": - version: 1.4.5 - resolution: "end-of-stream@npm:1.4.5" - dependencies: - once: "npm:^1.4.0" - checksum: 10c0/b0701c92a10b89afb1cb45bf54a5292c6f008d744eb4382fa559d54775ff31617d1d7bc3ef617575f552e24fad2c7c1a1835948c66b3f3a4be0a6c1f35c883d8 - languageName: node - linkType: hard - "env-paths@npm:^2.2.0": version: 2.2.1 resolution: "env-paths@npm:2.2.1" @@ -1720,55 +1894,127 @@ __metadata: languageName: node linkType: hard -"escalade@npm:^3.1.1": - version: 3.2.0 - resolution: "escalade@npm:3.2.0" - checksum: 10c0/ced4dd3a78e15897ed3be74e635110bbf3b08877b0a41be50dcb325ee0e0b5f65fc2d50e9845194d7c4633f327e2e1c6cce00a71b617c5673df0374201d67f65 +"es-module-lexer@npm:^1.7.0": + version: 1.7.0 + resolution: "es-module-lexer@npm:1.7.0" + checksum: 10c0/4c935affcbfeba7fb4533e1da10fa8568043df1e3574b869385980de9e2d475ddc36769891936dbb07036edb3c3786a8b78ccf44964cd130dedc1f2c984b6c7b languageName: node linkType: hard -"escape-string-regexp@npm:^2.0.0": - version: 2.0.0 - resolution: "escape-string-regexp@npm:2.0.0" - checksum: 10c0/2530479fe8db57eace5e8646c9c2a9c80fa279614986d16dcc6bcaceb63ae77f05a851ba6c43756d816c61d7f4534baf56e3c705e3e0d884818a46808811c507 +"es-toolkit@npm:^1.39.8": + version: 1.39.10 + resolution: "es-toolkit@npm:1.39.10" + dependenciesMeta: + "@trivago/prettier-plugin-sort-imports@4.3.0": + unplugged: true + prettier-plugin-sort-re-exports@0.0.1: + unplugged: true + checksum: 10c0/244dd6be25bc8c7af9f085f5b9aae08169eca760fc7d4735020f8f711b6a572e0bf205400326fa85a7924e20747d315756dba1b3a5f0d2887231374ec3651a98 languageName: node linkType: hard -"escape-string-regexp@npm:^5.0.0": - version: 5.0.0 - resolution: "escape-string-regexp@npm:5.0.0" - checksum: 10c0/6366f474c6f37a802800a435232395e04e9885919873e382b157ab7e8f0feb8fed71497f84a6f6a81a49aab41815522f5839112bd38026d203aea0c91622df95 - languageName: node - linkType: hard - -"esprima@npm:^4.0.0": - version: 4.0.1 - resolution: "esprima@npm:4.0.1" +"esbuild@npm:^0.25.0": + version: 0.25.9 + resolution: "esbuild@npm:0.25.9" + dependencies: + "@esbuild/aix-ppc64": "npm:0.25.9" + "@esbuild/android-arm": "npm:0.25.9" + "@esbuild/android-arm64": "npm:0.25.9" + "@esbuild/android-x64": "npm:0.25.9" + "@esbuild/darwin-arm64": "npm:0.25.9" + "@esbuild/darwin-x64": "npm:0.25.9" + "@esbuild/freebsd-arm64": "npm:0.25.9" + "@esbuild/freebsd-x64": "npm:0.25.9" + "@esbuild/linux-arm": "npm:0.25.9" + "@esbuild/linux-arm64": "npm:0.25.9" + "@esbuild/linux-ia32": "npm:0.25.9" + "@esbuild/linux-loong64": "npm:0.25.9" + "@esbuild/linux-mips64el": "npm:0.25.9" + "@esbuild/linux-ppc64": "npm:0.25.9" + "@esbuild/linux-riscv64": "npm:0.25.9" + "@esbuild/linux-s390x": "npm:0.25.9" + "@esbuild/linux-x64": "npm:0.25.9" + "@esbuild/netbsd-arm64": "npm:0.25.9" + "@esbuild/netbsd-x64": "npm:0.25.9" + "@esbuild/openbsd-arm64": "npm:0.25.9" + "@esbuild/openbsd-x64": "npm:0.25.9" + "@esbuild/openharmony-arm64": "npm:0.25.9" + "@esbuild/sunos-x64": "npm:0.25.9" + "@esbuild/win32-arm64": "npm:0.25.9" + "@esbuild/win32-ia32": "npm:0.25.9" + "@esbuild/win32-x64": "npm:0.25.9" + dependenciesMeta: + "@esbuild/aix-ppc64": + optional: true + "@esbuild/android-arm": + optional: true + "@esbuild/android-arm64": + optional: true + "@esbuild/android-x64": + optional: true + "@esbuild/darwin-arm64": + optional: true + "@esbuild/darwin-x64": + optional: true + "@esbuild/freebsd-arm64": + optional: true + "@esbuild/freebsd-x64": + optional: true + "@esbuild/linux-arm": + optional: true + "@esbuild/linux-arm64": + optional: true + "@esbuild/linux-ia32": + optional: true + "@esbuild/linux-loong64": + optional: true + "@esbuild/linux-mips64el": + optional: true + "@esbuild/linux-ppc64": + optional: true + "@esbuild/linux-riscv64": + optional: true + "@esbuild/linux-s390x": + optional: true + "@esbuild/linux-x64": + optional: true + "@esbuild/netbsd-arm64": + optional: true + "@esbuild/netbsd-x64": + optional: true + "@esbuild/openbsd-arm64": + optional: true + "@esbuild/openbsd-x64": + optional: true + "@esbuild/openharmony-arm64": + optional: true + "@esbuild/sunos-x64": + optional: true + "@esbuild/win32-arm64": + optional: true + "@esbuild/win32-ia32": + optional: true + "@esbuild/win32-x64": + optional: true bin: - esparse: ./bin/esparse.js - esvalidate: ./bin/esvalidate.js - checksum: 10c0/ad4bab9ead0808cf56501750fd9d3fb276f6b105f987707d059005d57e182d18a7c9ec7f3a01794ebddcca676773e42ca48a32d67a250c9d35e009ca613caba3 + esbuild: bin/esbuild + checksum: 10c0/aaa1284c75fcf45c82f9a1a117fe8dc5c45628e3386bda7d64916ae27730910b51c5aec7dd45a6ba19256be30ba2935e64a8f011a3f0539833071e06bf76d5b3 languageName: node linkType: hard -"estree-walker@npm:2.0.2, estree-walker@npm:^2.0.2": - version: 2.0.2 - resolution: "estree-walker@npm:2.0.2" - checksum: 10c0/53a6c54e2019b8c914dc395890153ffdc2322781acf4bd7d1a32d7aedc1710807bdcd866ac133903d5629ec601fbb50abe8c2e5553c7f5a0afdd9b6af6c945af +"estree-walker@npm:^3.0.3": + version: 3.0.3 + resolution: "estree-walker@npm:3.0.3" + dependencies: + "@types/estree": "npm:^1.0.0" + checksum: 10c0/c12e3c2b2642d2bcae7d5aa495c60fa2f299160946535763969a1c83fc74518ffa9c2cd3a8b69ac56aea547df6a8aac25f729a342992ef0bbac5f1c73e78995d languageName: node linkType: hard -"esutils@npm:^2.0.3": - version: 2.0.3 - resolution: "esutils@npm:2.0.3" - checksum: 10c0/9a2fe69a41bfdade834ba7c42de4723c97ec776e40656919c62cbd13607c45e127a003f05f724a1ea55e5029a4cf2de444b13009f2af71271e42d93a637137c7 - languageName: node - linkType: hard - -"expand-template@npm:^2.0.3": - version: 2.0.3 - resolution: "expand-template@npm:2.0.3" - checksum: 10c0/1c9e7afe9acadf9d373301d27f6a47b34e89b3391b1ef38b7471d381812537ef2457e620ae7f819d2642ce9c43b189b3583813ec395e2938319abe356a9b2f51 +"expect-type@npm:^1.2.1": + version: 1.2.2 + resolution: "expect-type@npm:1.2.2" + checksum: 10c0/6019019566063bbc7a690d9281d920b1a91284a4a093c2d55d71ffade5ac890cf37a51e1da4602546c4b56569d2ad2fc175a2ccee77d1ae06cb3af91ef84f44b languageName: node linkType: hard @@ -1797,76 +2043,15 @@ __metadata: languageName: node linkType: hard -"fast-diff@npm:^1.2.0": - version: 1.3.0 - resolution: "fast-diff@npm:1.3.0" - checksum: 10c0/5c19af237edb5d5effda008c891a18a585f74bf12953be57923f17a3a4d0979565fc64dbc73b9e20926b9d895f5b690c618cbb969af0cf022e3222471220ad29 - languageName: node - linkType: hard - -"fast-glob@npm:^3.3.3": - version: 3.3.3 - resolution: "fast-glob@npm:3.3.3" - dependencies: - "@nodelib/fs.stat": "npm:^2.0.2" - "@nodelib/fs.walk": "npm:^1.2.3" - glob-parent: "npm:^5.1.2" - merge2: "npm:^1.3.0" - micromatch: "npm:^4.0.8" - checksum: 10c0/f6aaa141d0d3384cf73cbcdfc52f475ed293f6d5b65bfc5def368b09163a9f7e5ec2b3014d80f733c405f58e470ee0cc451c2937685045cddcdeaa24199c43fe - languageName: node - linkType: hard - -"fastq@npm:^1.6.0": - version: 1.19.1 - resolution: "fastq@npm:1.19.1" - dependencies: - reusify: "npm:^1.0.4" - checksum: 10c0/ebc6e50ac7048daaeb8e64522a1ea7a26e92b3cee5cd1c7f2316cdca81ba543aa40a136b53891446ea5c3a67ec215fbaca87ad405f102dd97012f62916905630 - languageName: node - linkType: hard - -"fdir@npm:^6.4.4": - version: 6.4.6 - resolution: "fdir@npm:6.4.6" +"fdir@npm:^6.5.0": + version: 6.5.0 + resolution: "fdir@npm:6.5.0" peerDependencies: picomatch: ^3 || ^4 peerDependenciesMeta: picomatch: optional: true - checksum: 10c0/45b559cff889934ebb8bc498351e5acba40750ada7e7d6bde197768d2fa67c149be8ae7f8ff34d03f4e1eb20f2764116e56440aaa2f6689e9a4aa7ef06acafe9 - languageName: node - linkType: hard - -"figures@npm:^6.1.0": - version: 6.1.0 - resolution: "figures@npm:6.1.0" - dependencies: - is-unicode-supported: "npm:^2.0.0" - checksum: 10c0/9159df4264d62ef447a3931537de92f5012210cf5135c35c010df50a2169377581378149abfe1eb238bd6acbba1c0d547b1f18e0af6eee49e30363cedaffcfe4 - languageName: node - linkType: hard - -"file-uri-to-path@npm:1.0.0": - version: 1.0.0 - resolution: "file-uri-to-path@npm:1.0.0" - checksum: 10c0/3b545e3a341d322d368e880e1c204ef55f1d45cdea65f7efc6c6ce9e0c4d22d802d5629320eb779d006fe59624ac17b0e848d83cc5af7cd101f206cb704f5519 - languageName: node - linkType: hard - -"fill-range@npm:^7.1.1": - version: 7.1.1 - resolution: "fill-range@npm:7.1.1" - dependencies: - to-regex-range: "npm:^5.0.1" - checksum: 10c0/b75b691bbe065472f38824f694c2f7449d7f5004aa950426a2c28f0306c60db9b880c0b0e4ed819997ffb882d1da02cfcfc819bddc94d71627f5269682edf018 - languageName: node - linkType: hard - -"find-up-simple@npm:^1.0.0": - version: 1.0.1 - resolution: "find-up-simple@npm:1.0.1" - checksum: 10c0/ad34de157b7db925d50ff78302fefb28e309f3bc947c93ffca0f9b0bccf9cf1a2dc57d805d5c94ec9fc60f4838f5dbdfd2a48ecd77c23015fa44c6dd5f60bc40 + checksum: 10c0/e345083c4306b3aed6cb8ec551e26c36bab5c511e99ea4576a16750ddc8d3240e63826cc624f5ae17ad4dc82e68a253213b60d556c11bfad064b7607847ed07f languageName: node linkType: hard @@ -1891,13 +2076,6 @@ __metadata: languageName: node linkType: hard -"fs-constants@npm:^1.0.0": - version: 1.0.0 - resolution: "fs-constants@npm:1.0.0" - checksum: 10c0/a0cde99085f0872f4d244e83e03a46aa387b74f5a5af750896c6b05e9077fac00e9932fdf5aef84f2f16634cd473c63037d7a512576da7d5c2b9163d1909f3a8 - languageName: node - linkType: hard - "fs-minipass@npm:^3.0.0": version: 3.0.3 resolution: "fs-minipass@npm:3.0.3" @@ -1907,37 +2085,45 @@ __metadata: languageName: node linkType: hard -"get-caller-file@npm:^2.0.5": - version: 2.0.5 - resolution: "get-caller-file@npm:2.0.5" - checksum: 10c0/c6c7b60271931fa752aeb92f2b47e355eac1af3a2673f47c9589e8f8a41adc74d45551c1bc57b5e66a80609f10ffb72b6f575e4370d61cc3f7f3aaff01757cde - languageName: node - linkType: hard - -"get-east-asian-width@npm:^1.0.0": - version: 1.3.0 - resolution: "get-east-asian-width@npm:1.3.0" - checksum: 10c0/1a049ba697e0f9a4d5514c4623781c5246982bdb61082da6b5ae6c33d838e52ce6726407df285cdbb27ec1908b333cf2820989bd3e986e37bb20979437fdf34b - languageName: node - linkType: hard - -"github-from-package@npm:0.0.0": - version: 0.0.0 - resolution: "github-from-package@npm:0.0.0" - checksum: 10c0/737ee3f52d0a27e26332cde85b533c21fcdc0b09fb716c3f8e522cfaa9c600d4a631dec9fcde179ec9d47cca89017b7848ed4d6ae6b6b78f936c06825b1fcc12 - languageName: node - linkType: hard - -"glob-parent@npm:^5.1.2": - version: 5.1.2 - resolution: "glob-parent@npm:5.1.2" +"fsevents@npm:2.3.2": + version: 2.3.2 + resolution: "fsevents@npm:2.3.2" dependencies: - is-glob: "npm:^4.0.1" - checksum: 10c0/cab87638e2112bee3f839ef5f6e0765057163d39c66be8ec1602f3823da4692297ad4e972de876ea17c44d652978638d2fd583c6713d0eb6591706825020c9ee + node-gyp: "npm:latest" + checksum: 10c0/be78a3efa3e181cda3cf7a4637cb527bcebb0bd0ea0440105a3bb45b86f9245b307dc10a2507e8f4498a7d4ec349d1910f4d73e4d4495b16103106e07eee735b + conditions: os=darwin languageName: node linkType: hard -"glob@npm:^10.2.2, glob@npm:^10.4.5": +"fsevents@npm:~2.3.2, fsevents@npm:~2.3.3": + version: 2.3.3 + resolution: "fsevents@npm:2.3.3" + dependencies: + node-gyp: "npm:latest" + checksum: 10c0/a1f0c44595123ed717febbc478aa952e47adfc28e2092be66b8ab1635147254ca6cfe1df792a8997f22716d4cbafc73309899ff7bfac2ac3ad8cf2e4ecc3ec60 + conditions: os=darwin + languageName: node + linkType: hard + +"fsevents@patch:fsevents@npm%3A2.3.2#optional!builtin": + version: 2.3.2 + resolution: "fsevents@patch:fsevents@npm%3A2.3.2#optional!builtin::version=2.3.2&hash=df0bf1" + dependencies: + node-gyp: "npm:latest" + conditions: os=darwin + languageName: node + linkType: hard + +"fsevents@patch:fsevents@npm%3A~2.3.2#optional!builtin, fsevents@patch:fsevents@npm%3A~2.3.3#optional!builtin": + version: 2.3.3 + resolution: "fsevents@patch:fsevents@npm%3A2.3.3#optional!builtin::version=2.3.3&hash=df0bf1" + dependencies: + node-gyp: "npm:latest" + conditions: os=darwin + languageName: node + linkType: hard + +"glob@npm:^10.2.2": version: 10.4.5 resolution: "glob@npm:10.4.5" dependencies: @@ -1953,21 +2139,7 @@ __metadata: languageName: node linkType: hard -"globby@npm:^14.1.0": - version: 14.1.0 - resolution: "globby@npm:14.1.0" - dependencies: - "@sindresorhus/merge-streams": "npm:^2.1.0" - fast-glob: "npm:^3.3.3" - ignore: "npm:^7.0.3" - path-type: "npm:^6.0.0" - slash: "npm:^5.1.0" - unicorn-magic: "npm:^0.3.0" - checksum: 10c0/527a1063c5958255969620c6fa4444a2b2e9278caddd571d46dfbfa307cb15977afb746e84d682ba5b6c94fc081e8997f80ff05dd235441ba1cb16f86153e58e - languageName: node - linkType: hard - -"graceful-fs@npm:^4.2.6, graceful-fs@npm:^4.2.9": +"graceful-fs@npm:^4.2.6": version: 4.2.11 resolution: "graceful-fs@npm:4.2.11" checksum: 10c0/386d011a553e02bc594ac2ca0bd6d9e4c22d7fa8cfbfc448a6d148c59ea881b092db9dbe3547ae4b88e55f1b01f7c4a2ecc53b310c042793e63aa44cf6c257f2 @@ -1991,7 +2163,7 @@ __metadata: languageName: node linkType: hard -"https-proxy-agent@npm:^7.0.1, https-proxy-agent@npm:^7.0.5": +"https-proxy-agent@npm:^7.0.1": version: 7.0.6 resolution: "https-proxy-agent@npm:7.0.6" dependencies: @@ -2019,27 +2191,6 @@ __metadata: languageName: node linkType: hard -"ieee754@npm:^1.1.13": - version: 1.2.1 - resolution: "ieee754@npm:1.2.1" - checksum: 10c0/b0782ef5e0935b9f12883a2e2aa37baa75da6e66ce6515c168697b42160807d9330de9a32ec1ed73149aea02e0d822e572bca6f1e22bdcbd2149e13b050b17bb - languageName: node - linkType: hard - -"ignore-by-default@npm:^2.1.0": - version: 2.1.0 - resolution: "ignore-by-default@npm:2.1.0" - checksum: 10c0/3a6040dac25ed9da39dee73bf1634fdd1e15b0eb7cf52a6bdec81c310565782d8811c104ce40acb3d690d61c5fc38a91c78e6baee830a8a2232424dbc6b66981 - languageName: node - linkType: hard - -"ignore@npm:^7.0.3": - version: 7.0.5 - resolution: "ignore@npm:7.0.5" - checksum: 10c0/ae00db89fe873064a093b8999fe4cc284b13ef2a178636211842cceb650b9c3e390d3339191acb145d81ed5379d2074840cf0c33a20bdbd6f32821f79eb4ad5d - languageName: node - linkType: hard - "imurmurhash@npm:^0.1.4": version: 0.1.4 resolution: "imurmurhash@npm:0.1.4" @@ -2047,48 +2198,10 @@ __metadata: languageName: node linkType: hard -"indent-string@npm:^5.0.0": - version: 5.0.0 - resolution: "indent-string@npm:5.0.0" - checksum: 10c0/8ee77b57d92e71745e133f6f444d6fa3ed503ad0e1bcd7e80c8da08b42375c07117128d670589725ed07b1978065803fa86318c309ba45415b7fe13e7f170220 - languageName: node - linkType: hard - -"inherits@npm:^2.0.3, inherits@npm:^2.0.4": - version: 2.0.4 - resolution: "inherits@npm:2.0.4" - checksum: 10c0/4e531f648b29039fb7426fb94075e6545faa1eb9fe83c29f0b6d9e7263aceb4289d2d4557db0d428188eeb449cc7c5e77b0a0b2c4e248ff2a65933a0dee49ef2 - languageName: node - linkType: hard - -"ini@npm:~1.3.0": - version: 1.3.8 - resolution: "ini@npm:1.3.8" - checksum: 10c0/ec93838d2328b619532e4f1ff05df7909760b6f66d9c9e2ded11e5c1897d6f2f9980c54dd638f88654b00919ce31e827040631eab0a3969e4d1abefa0719516a - languageName: node - linkType: hard - -"ip-address@npm:^9.0.5": - version: 9.0.5 - resolution: "ip-address@npm:9.0.5" - dependencies: - jsbn: "npm:1.1.0" - sprintf-js: "npm:^1.1.3" - checksum: 10c0/331cd07fafcb3b24100613e4b53e1a2b4feab11e671e655d46dc09ee233da5011284d09ca40c4ecbdfe1d0004f462958675c224a804259f2f78d2465a87824bc - languageName: node - linkType: hard - -"irregular-plurals@npm:^3.3.0": - version: 3.5.0 - resolution: "irregular-plurals@npm:3.5.0" - checksum: 10c0/7c033bbe7325e5a6e0a26949cc6863b6ce273403d4cd5b93bd99b33fecb6605b0884097c4259c23ed0c52c2133bf7d1cdcdd7a0630e8c325161fe269b3447918 - languageName: node - linkType: hard - -"is-extglob@npm:^2.1.1": - version: 2.1.1 - resolution: "is-extglob@npm:2.1.1" - checksum: 10c0/5487da35691fbc339700bbb2730430b07777a3c21b9ebaecb3072512dfd7b4ba78ac2381a87e8d78d20ea08affb3f1971b4af629173a6bf435ff8a4c47747912 +"ip-address@npm:^10.0.1": + version: 10.0.1 + resolution: "ip-address@npm:10.0.1" + checksum: 10c0/1634d79dae18394004775cb6d699dc46b7c23df6d2083164025a2b15240c1164fccde53d0e08bd5ee4fc53913d033ab6b5e395a809ad4b956a940c446e948843 languageName: node linkType: hard @@ -2099,50 +2212,6 @@ __metadata: languageName: node linkType: hard -"is-fullwidth-code-point@npm:^4.0.0": - version: 4.0.0 - resolution: "is-fullwidth-code-point@npm:4.0.0" - checksum: 10c0/df2a717e813567db0f659c306d61f2f804d480752526886954a2a3e2246c7745fd07a52b5fecf2b68caf0a6c79dcdace6166fdf29cc76ed9975cc334f0a018b8 - languageName: node - linkType: hard - -"is-glob@npm:^4.0.1": - version: 4.0.3 - resolution: "is-glob@npm:4.0.3" - dependencies: - is-extglob: "npm:^2.1.1" - checksum: 10c0/17fb4014e22be3bbecea9b2e3a76e9e34ff645466be702f1693e8f1ee1adac84710d0be0bd9f967d6354036fd51ab7c2741d954d6e91dae6bb69714de92c197a - languageName: node - linkType: hard - -"is-number@npm:^7.0.0": - version: 7.0.0 - resolution: "is-number@npm:7.0.0" - checksum: 10c0/b4686d0d3053146095ccd45346461bc8e53b80aeb7671cc52a4de02dbbf7dc0d1d2a986e2fe4ae206984b4d34ef37e8b795ebc4f4295c978373e6575e295d811 - languageName: node - linkType: hard - -"is-plain-object@npm:^5.0.0": - version: 5.0.0 - resolution: "is-plain-object@npm:5.0.0" - checksum: 10c0/893e42bad832aae3511c71fd61c0bf61aa3a6d853061c62a307261842727d0d25f761ce9379f7ba7226d6179db2a3157efa918e7fe26360f3bf0842d9f28942c - languageName: node - linkType: hard - -"is-promise@npm:^4.0.0": - version: 4.0.0 - resolution: "is-promise@npm:4.0.0" - checksum: 10c0/ebd5c672d73db781ab33ccb155fb9969d6028e37414d609b115cc534654c91ccd061821d5b987eefaa97cf4c62f0b909bb2f04db88306de26e91bfe8ddc01503 - languageName: node - linkType: hard - -"is-unicode-supported@npm:^2.0.0": - version: 2.1.0 - resolution: "is-unicode-supported@npm:2.1.0" - checksum: 10c0/a0f53e9a7c1fdbcf2d2ef6e40d4736fdffff1c9f8944c75e15425118ff3610172c87bf7bc6c34d3903b04be59790bb2212ddbe21ee65b5a97030fc50370545a5 - languageName: node - linkType: hard - "isexe@npm:^2.0.0": version: 2.0.0 resolution: "isexe@npm:2.0.0" @@ -2170,22 +2239,17 @@ __metadata: languageName: node linkType: hard -"js-string-escape@npm:^1.0.1": - version: 1.0.1 - resolution: "js-string-escape@npm:1.0.1" - checksum: 10c0/2c33b9ff1ba6b84681c51ca0997e7d5a1639813c95d5b61cb7ad47e55cc28fa4a0b1935c3d218710d8e6bcee5d0cd8c44755231e3a4e45fc604534d9595a3628 +"js-tokens@npm:^4.0.0": + version: 4.0.0 + resolution: "js-tokens@npm:4.0.0" + checksum: 10c0/e248708d377aa058eacf2037b07ded847790e6de892bbad3dac0abba2e759cb9f121b00099a65195616badcb6eca8d14d975cb3e89eb1cfda644756402c8aeed languageName: node linkType: hard -"js-yaml@npm:^3.14.1": - version: 3.14.1 - resolution: "js-yaml@npm:3.14.1" - dependencies: - argparse: "npm:^1.0.7" - esprima: "npm:^4.0.0" - bin: - js-yaml: bin/js-yaml.js - checksum: 10c0/6746baaaeac312c4db8e75fa22331d9a04cccb7792d126ed8ce6a0bbcfef0cedaddd0c5098fade53db067c09fe00aa1c957674b4765610a8b06a5a189e46433b +"js-tokens@npm:^9.0.1": + version: 9.0.1 + resolution: "js-tokens@npm:9.0.1" + checksum: 10c0/68dcab8f233dde211a6b5fd98079783cbcd04b53617c1250e3553ee16ab3e6134f5e65478e41d82f6d351a052a63d71024553933808570f04dbf828d7921e80e languageName: node linkType: hard @@ -2200,20 +2264,6 @@ __metadata: languageName: node linkType: hard -"jsbn@npm:1.1.0": - version: 1.1.0 - resolution: "jsbn@npm:1.1.0" - checksum: 10c0/4f907fb78d7b712e11dea8c165fe0921f81a657d3443dde75359ed52eb2b5d33ce6773d97985a089f09a65edd80b11cb75c767b57ba47391fee4c969f7215c96 - languageName: node - linkType: hard - -"load-json-file@npm:^7.0.1": - version: 7.0.1 - resolution: "load-json-file@npm:7.0.1" - checksum: 10c0/7117459608a0b6329c7f78e6e1f541b3162dd901c29dd5af721fec8b270177d2e3d7999c971f344fff04daac368d052732e2c7146014bc84d15e0b636975e19a - languageName: node - linkType: hard - "locate-path@npm:^7.2.0": version: 7.2.0 resolution: "locate-path@npm:7.2.0" @@ -2223,17 +2273,10 @@ __metadata: languageName: node linkType: hard -"lodash-es@npm:^4.17.21": - version: 4.17.21 - resolution: "lodash-es@npm:4.17.21" - checksum: 10c0/fb407355f7e6cd523a9383e76e6b455321f0f153a6c9625e21a8827d10c54c2a2341bd2ae8d034358b60e07325e1330c14c224ff582d04612a46a4f0479ff2f2 - languageName: node - linkType: hard - -"lodash@npm:^4.17.15": - version: 4.17.21 - resolution: "lodash@npm:4.17.21" - checksum: 10c0/d8cbea072bb08655bb4c989da418994b073a608dffa608b09ac04b43a791b12aeae7cd7ad919aa4c925f33b48490b5cfe6c1f71d827956071dae2e7bb3a6b74c +"loupe@npm:^3.1.0, loupe@npm:^3.1.4": + version: 3.2.1 + resolution: "loupe@npm:3.2.1" + checksum: 10c0/910c872cba291309664c2d094368d31a68907b6f5913e989d301b5c25f30e97d76d77f23ab3bf3b46d0f601ff0b6af8810c10c31b91d2c6b2f132809ca2cc705 languageName: node linkType: hard @@ -2244,6 +2287,24 @@ __metadata: languageName: node linkType: hard +"lz-string@npm:^1.5.0": + version: 1.5.0 + resolution: "lz-string@npm:1.5.0" + bin: + lz-string: bin/bin.js + checksum: 10c0/36128e4de34791838abe979b19927c26e67201ca5acf00880377af7d765b38d1c60847e01c5ec61b1a260c48029084ab3893a3925fd6e48a04011364b089991b + languageName: node + linkType: hard + +"magic-string@npm:^0.30.17": + version: 0.30.18 + resolution: "magic-string@npm:0.30.18" + dependencies: + "@jridgewell/sourcemap-codec": "npm:^1.5.5" + checksum: 10c0/80fba01e13ce1f5c474a0498a5aa462fa158eb56567310747089a0033e432d83a2021ee2c109ac116010cd9dcf90a5231d89fbe3858165f73c00a50a74dbefcd + languageName: node + linkType: hard + "make-fetch-happen@npm:^14.0.3": version: 14.0.3 resolution: "make-fetch-happen@npm:14.0.3" @@ -2263,64 +2324,6 @@ __metadata: languageName: node linkType: hard -"matcher@npm:^5.0.0": - version: 5.0.0 - resolution: "matcher@npm:5.0.0" - dependencies: - escape-string-regexp: "npm:^5.0.0" - checksum: 10c0/eda5471fc9d5b7264d63c81727824adc3585ddb5cfdc5fce5a9b7c86f946ff181610735d330b1c37a84811df872d1290bf4e9401d2be2a414204343701144b18 - languageName: node - linkType: hard - -"md5-hex@npm:^3.0.1": - version: 3.0.1 - resolution: "md5-hex@npm:3.0.1" - dependencies: - blueimp-md5: "npm:^2.10.0" - checksum: 10c0/ee2b4d8da16b527b3a3fe4d7a96720f43afd07b46a82d49421208b5a126235fb75cfb30b80d4029514772c8844273f940bddfbf4155c787f968f3be4060d01e4 - languageName: node - linkType: hard - -"memoize@npm:^10.1.0": - version: 10.1.0 - resolution: "memoize@npm:10.1.0" - dependencies: - mimic-function: "npm:^5.0.1" - checksum: 10c0/6cf71f673b89778b05cd1131f573ba858627daa8fec60f2197328386acf7ab184a89e52527abbd5a605b5ccf5ee12dc0cb96efb651d9a30dcfcc89e9baacc84d - languageName: node - linkType: hard - -"merge2@npm:^1.3.0": - version: 1.4.1 - resolution: "merge2@npm:1.4.1" - checksum: 10c0/254a8a4605b58f450308fc474c82ac9a094848081bf4c06778200207820e5193726dc563a0d2c16468810516a5c97d9d3ea0ca6585d23c58ccfff2403e8dbbeb - languageName: node - linkType: hard - -"micromatch@npm:^4.0.8": - version: 4.0.8 - resolution: "micromatch@npm:4.0.8" - dependencies: - braces: "npm:^3.0.3" - picomatch: "npm:^2.3.1" - checksum: 10c0/166fa6eb926b9553f32ef81f5f531d27b4ce7da60e5baf8c021d043b27a388fb95e46a8038d5045877881e673f8134122b59624d5cecbd16eb50a42e7a6b5ca8 - languageName: node - linkType: hard - -"mimic-function@npm:^5.0.1": - version: 5.0.1 - resolution: "mimic-function@npm:5.0.1" - checksum: 10c0/f3d9464dd1816ecf6bdf2aec6ba32c0728022039d992f178237d8e289b48764fee4131319e72eedd4f7f094e22ded0af836c3187a7edc4595d28dd74368fd81d - languageName: node - linkType: hard - -"mimic-response@npm:^3.1.0": - version: 3.1.0 - resolution: "mimic-response@npm:3.1.0" - checksum: 10c0/0d6f07ce6e03e9e4445bee655202153bdb8a98d67ee8dc965ac140900d7a2688343e6b4c9a72cfc9ef2f7944dfd76eef4ab2482eb7b293a68b84916bac735362 - languageName: node - linkType: hard - "minimatch@npm:^9.0.4": version: 9.0.5 resolution: "minimatch@npm:9.0.5" @@ -2330,13 +2333,6 @@ __metadata: languageName: node linkType: hard -"minimist@npm:^1.2.0, minimist@npm:^1.2.3": - version: 1.2.8 - resolution: "minimist@npm:1.2.8" - checksum: 10c0/19d3fcdca050087b84c2029841a093691a91259a47def2f18222f41e7645a0b7c44ef4b40e88a1e58a40c84d2ef0ee6047c55594d298146d0eb3f6b737c20ce6 - languageName: node - linkType: hard - "minipass-collect@npm:^2.0.1": version: 2.0.1 resolution: "minipass-collect@npm:2.0.1" @@ -2413,13 +2409,6 @@ __metadata: languageName: node linkType: hard -"mkdirp-classic@npm:^0.5.2, mkdirp-classic@npm:^0.5.3": - version: 0.5.3 - resolution: "mkdirp-classic@npm:0.5.3" - checksum: 10c0/95371d831d196960ddc3833cc6907e6b8f67ac5501a6582f47dfae5eb0f092e9f8ce88e0d83afcae95d6e2b61a01741ba03714eeafb6f7a6e9dcc158ac85b168 - languageName: node - linkType: hard - "mkdirp@npm:^3.0.1": version: 3.0.1 resolution: "mkdirp@npm:3.0.1" @@ -2429,6 +2418,13 @@ __metadata: languageName: node linkType: hard +"mrmime@npm:^2.0.0": + version: 2.0.1 + resolution: "mrmime@npm:2.0.1" + checksum: 10c0/af05afd95af202fdd620422f976ad67dc18e6ee29beb03dd1ce950ea6ef664de378e44197246df4c7cdd73d47f2e7143a6e26e473084b9e4aa2095c0ad1e1761 + languageName: node + linkType: hard + "ms@npm:^2.1.3": version: 2.1.3 resolution: "ms@npm:2.1.3" @@ -2443,10 +2439,12 @@ __metadata: languageName: node linkType: hard -"napi-build-utils@npm:^2.0.0": - version: 2.0.0 - resolution: "napi-build-utils@npm:2.0.0" - checksum: 10c0/5833aaeb5cc5c173da47a102efa4680a95842c13e0d9cc70428bd3ee8d96bb2172f8860d2811799b5daa5cbeda779933601492a2028a6a5351c6d0fcf6de83db +"nanoid@npm:^3.3.11": + version: 3.3.11 + resolution: "nanoid@npm:3.3.11" + bin: + nanoid: bin/nanoid.cjs + checksum: 10c0/40e7f70b3d15f725ca072dfc4f74e81fcf1fbb02e491cf58ac0c79093adc9b0a73b152bcde57df4b79cd097e13023d7504acb38404a4da7bc1cd8e887b82fe0b languageName: node linkType: hard @@ -2457,43 +2455,9 @@ __metadata: languageName: node linkType: hard -"node-abi@npm:^3.3.0": - version: 3.75.0 - resolution: "node-abi@npm:3.75.0" - dependencies: - semver: "npm:^7.3.5" - checksum: 10c0/c43a2409407df3737848fd96202b0a49e15039994aecce963969e9ef7342a8fc544aba94e0bfd8155fb9de5f5fe9a4b6ccad8bf509e7c46caf096fc4491d63f2 - languageName: node - linkType: hard - -"node-fetch@npm:^2.6.7": - version: 2.7.0 - resolution: "node-fetch@npm:2.7.0" - dependencies: - whatwg-url: "npm:^5.0.0" - peerDependencies: - encoding: ^0.1.0 - peerDependenciesMeta: - encoding: - optional: true - checksum: 10c0/b55786b6028208e6fbe594ccccc213cab67a72899c9234eb59dba51062a299ea853210fcf526998eaa2867b0963ad72338824450905679ff0fa304b8c5093ae8 - languageName: node - linkType: hard - -"node-gyp-build@npm:^4.2.2": - version: 4.8.4 - resolution: "node-gyp-build@npm:4.8.4" - bin: - node-gyp-build: bin.js - node-gyp-build-optional: optional.js - node-gyp-build-test: build-test.js - checksum: 10c0/444e189907ece2081fe60e75368784f7782cfddb554b60123743dfb89509df89f1f29c03bbfa16b3a3e0be3f48799a4783f487da6203245fa5bed239ba7407e1 - languageName: node - linkType: hard - "node-gyp@npm:latest": - version: 11.3.0 - resolution: "node-gyp@npm:11.3.0" + version: 11.4.2 + resolution: "node-gyp@npm:11.4.2" dependencies: env-paths: "npm:^2.2.0" exponential-backoff: "npm:^3.1.1" @@ -2507,14 +2471,7 @@ __metadata: which: "npm:^5.0.0" bin: node-gyp: bin/node-gyp.js - checksum: 10c0/5f4ad5a729386f7b50096efd4934b06c071dbfbc7d7d541a66d6959a7dccd62f53ff3dc95fffb60bf99d8da1270e23769f82246fcaa6c5645a70c967ae9a3398 - languageName: node - linkType: hard - -"nofilter@npm:^3.0.2": - version: 3.1.0 - resolution: "nofilter@npm:3.1.0" - checksum: 10c0/92459f3864a067b347032263f0b536223cbfc98153913b5dce350cb39c8470bc1813366e41993f22c33cc6400c0f392aa324a4b51e24c22040635c1cdb046499 + checksum: 10c0/0bfd3e96770ed70f07798d881dd37b4267708966d868a0e585986baac487d9cf5831285579fd629a83dc4e434f53e6416ce301097f2ee464cb74d377e4d8bdbe languageName: node linkType: hard @@ -2529,15 +2486,6 @@ __metadata: languageName: node linkType: hard -"once@npm:^1.3.1, once@npm:^1.4.0": - version: 1.4.0 - resolution: "once@npm:1.4.0" - dependencies: - wrappy: "npm:1" - checksum: 10c0/5d48aca287dfefabd756621c5dfce5c91a549a93e9fdb7b8246bc4c4790aa2ec17b34a260530474635147aeb631a2dcc8b32c613df0675f96041cbb8244517d0 - languageName: node - linkType: hard - "os-tmpdir@npm:~1.0.2": version: 1.0.2 resolution: "os-tmpdir@npm:1.0.2" @@ -2563,23 +2511,13 @@ __metadata: languageName: node linkType: hard -"p-map@npm:^7.0.2, p-map@npm:^7.0.3": +"p-map@npm:^7.0.2": version: 7.0.3 resolution: "p-map@npm:7.0.3" checksum: 10c0/46091610da2b38ce47bcd1d8b4835a6fa4e832848a6682cf1652bc93915770f4617afc844c10a77d1b3e56d2472bb2d5622353fa3ead01a7f42b04fc8e744a5c languageName: node linkType: hard -"package-config@npm:^5.0.0": - version: 5.0.0 - resolution: "package-config@npm:5.0.0" - dependencies: - find-up-simple: "npm:^1.0.0" - load-json-file: "npm:^7.0.1" - checksum: 10c0/f6c48930700b73a41d839bf2898b628d23665827488a4f34aed2d05e4a99d7a70a70ada115c3546765947fbc8accff94c0779da21ea084b25df47cb774531eeb - languageName: node - linkType: hard - "package-json-from-dist@npm:^1.0.0": version: 1.0.1 resolution: "package-json-from-dist@npm:1.0.1" @@ -2587,13 +2525,6 @@ __metadata: languageName: node linkType: hard -"parse-ms@npm:^4.0.0": - version: 4.0.0 - resolution: "parse-ms@npm:4.0.0" - checksum: 10c0/a7900f4f1ebac24cbf5e9708c16fb2fd482517fad353aecd7aefb8c2ba2f85ce017913ccb8925d231770404780df46244ea6fec598b3bde6490882358b4d2d16 - languageName: node - linkType: hard - "path-exists@npm:^5.0.0": version: 5.0.0 resolution: "path-exists@npm:5.0.0" @@ -2618,64 +2549,77 @@ __metadata: languageName: node linkType: hard -"path-type@npm:^6.0.0": - version: 6.0.0 - resolution: "path-type@npm:6.0.0" - checksum: 10c0/55baa8b1187d6dc683d5a9cfcc866168d6adff58e5db91126795376d818eee46391e00b2a4d53e44d844c7524a7d96aa68cc68f4f3e500d3d069a39e6535481c +"pathe@npm:^2.0.3": + version: 2.0.3 + resolution: "pathe@npm:2.0.3" + checksum: 10c0/c118dc5a8b5c4166011b2b70608762e260085180bb9e33e80a50dcdb1e78c010b1624f4280c492c92b05fc276715a4c357d1f9edc570f8f1b3d90b6839ebaca1 languageName: node linkType: hard -"picomatch@npm:^2.3.1": - version: 2.3.1 - resolution: "picomatch@npm:2.3.1" - checksum: 10c0/26c02b8d06f03206fc2ab8d16f19960f2ff9e81a658f831ecb656d8f17d9edc799e8364b1f4a7873e89d9702dff96204be0fa26fe4181f6843f040f819dac4be +"pathval@npm:^2.0.0": + version: 2.0.1 + resolution: "pathval@npm:2.0.1" + checksum: 10c0/460f4709479fbf2c45903a65655fc8f0a5f6d808f989173aeef5fdea4ff4f303dc13f7870303999add60ec49d4c14733895c0a869392e9866f1091fa64fd7581 languageName: node linkType: hard -"picomatch@npm:^4.0.2": +"picocolors@npm:1.1.1, picocolors@npm:^1.1.1": + version: 1.1.1 + resolution: "picocolors@npm:1.1.1" + checksum: 10c0/e2e3e8170ab9d7c7421969adaa7e1b31434f789afb9b3f115f6b96d91945041ac3ceb02e9ec6fe6510ff036bcc0bf91e69a1772edc0b707e12b19c0f2d6bcf58 + languageName: node + linkType: hard + +"picomatch@npm:^4.0.2, picomatch@npm:^4.0.3": version: 4.0.3 resolution: "picomatch@npm:4.0.3" checksum: 10c0/9582c951e95eebee5434f59e426cddd228a7b97a0161a375aed4be244bd3fe8e3a31b846808ea14ef2c8a2527a6eeab7b3946a67d5979e81694654f939473ae2 languageName: node linkType: hard -"plur@npm:^5.1.0": - version: 5.1.0 - resolution: "plur@npm:5.1.0" - dependencies: - irregular-plurals: "npm:^3.3.0" - checksum: 10c0/26bb622b8545fcfd47bbf56fbcca66c08693708a232e403fa3589e00003c56c14231ac57c7588ca5db83ef4be1f61383402c4ea954000768f779f8aef6eb6da8 - languageName: node - linkType: hard - -"prebuild-install@npm:^7.1.1": - version: 7.1.3 - resolution: "prebuild-install@npm:7.1.3" - dependencies: - detect-libc: "npm:^2.0.0" - expand-template: "npm:^2.0.3" - github-from-package: "npm:0.0.0" - minimist: "npm:^1.2.3" - mkdirp-classic: "npm:^0.5.3" - napi-build-utils: "npm:^2.0.0" - node-abi: "npm:^3.3.0" - pump: "npm:^3.0.0" - rc: "npm:^1.2.7" - simple-get: "npm:^4.0.0" - tar-fs: "npm:^2.0.0" - tunnel-agent: "npm:^0.6.0" +"playwright-core@npm:1.55.0": + version: 1.55.0 + resolution: "playwright-core@npm:1.55.0" bin: - prebuild-install: bin.js - checksum: 10c0/25919a42b52734606a4036ab492d37cfe8b601273d8dfb1fa3c84e141a0a475e7bad3ab848c741d2f810cef892fcf6059b8c7fe5b29f98d30e0c29ad009bedff + playwright-core: cli.js + checksum: 10c0/c39d6aa30e7a4e73965942ca5e13405ae05c9cb49f755a35f04248c864c0b24cf662d9767f1797b3ec48d1cf4e54774dce4a19c16534bd5cfd2aa3da81c9dc3a languageName: node linkType: hard -"pretty-ms@npm:^9.2.0": - version: 9.2.0 - resolution: "pretty-ms@npm:9.2.0" +"playwright@npm:^1.55.0": + version: 1.55.0 + resolution: "playwright@npm:1.55.0" dependencies: - parse-ms: "npm:^4.0.0" - checksum: 10c0/ab6d066f90e9f77020426986e1b018369f41575674544c539aabec2e63a20fec01166d8cf6571d0e165ad11cfe5a8134a2a48a36d42ab291c59c6deca5264cbb + fsevents: "npm:2.3.2" + playwright-core: "npm:1.55.0" + dependenciesMeta: + fsevents: + optional: true + bin: + playwright: cli.js + checksum: 10c0/51605b7e57a5650e57972c5fdfc09d7a9934cca1cbee5beacca716fa801e25cb5bb7c1663de90c22b300fde884e5545a2b13a0505a93270b660687791c478304 + languageName: node + linkType: hard + +"postcss@npm:^8.5.6": + version: 8.5.6 + resolution: "postcss@npm:8.5.6" + dependencies: + nanoid: "npm:^3.3.11" + picocolors: "npm:^1.1.1" + source-map-js: "npm:^1.2.1" + checksum: 10c0/5127cc7c91ed7a133a1b7318012d8bfa112da9ef092dddf369ae699a1f10ebbd89b1b9f25f3228795b84585c72aabd5ced5fc11f2ba467eedf7b081a66fad024 + languageName: node + linkType: hard + +"pretty-format@npm:^27.0.2": + version: 27.5.1 + resolution: "pretty-format@npm:27.5.1" + dependencies: + ansi-regex: "npm:^5.0.1" + ansi-styles: "npm:^5.0.0" + react-is: "npm:^17.0.1" + checksum: 10c0/0cbda1031aa30c659e10921fa94e0dd3f903ecbbbe7184a729ad66f2b6e7f17891e8c7d7654c458fa4ccb1a411ffb695b4f17bbcd3fe075fabe181027c4040ed languageName: node linkType: hard @@ -2696,68 +2640,10 @@ __metadata: languageName: node linkType: hard -"pump@npm:^3.0.0": - version: 3.0.3 - resolution: "pump@npm:3.0.3" - dependencies: - end-of-stream: "npm:^1.1.0" - once: "npm:^1.3.1" - checksum: 10c0/ada5cdf1d813065bbc99aa2c393b8f6beee73b5de2890a8754c9f488d7323ffd2ca5f5a0943b48934e3fcbd97637d0337369c3c631aeb9614915db629f1c75c9 - languageName: node - linkType: hard - -"queue-microtask@npm:^1.2.2": - version: 1.2.3 - resolution: "queue-microtask@npm:1.2.3" - checksum: 10c0/900a93d3cdae3acd7d16f642c29a642aea32c2026446151f0778c62ac089d4b8e6c986811076e1ae180a694cedf077d453a11b58ff0a865629a4f82ab558e102 - languageName: node - linkType: hard - -"rc@npm:^1.2.7": - version: 1.2.8 - resolution: "rc@npm:1.2.8" - dependencies: - deep-extend: "npm:^0.6.0" - ini: "npm:~1.3.0" - minimist: "npm:^1.2.0" - strip-json-comments: "npm:~2.0.1" - bin: - rc: ./cli.js - checksum: 10c0/24a07653150f0d9ac7168e52943cc3cb4b7a22c0e43c7dff3219977c2fdca5a2760a304a029c20811a0e79d351f57d46c9bde216193a0f73978496afc2b85b15 - languageName: node - linkType: hard - -"readable-stream@npm:^3.1.1, readable-stream@npm:^3.4.0": - version: 3.6.2 - resolution: "readable-stream@npm:3.6.2" - dependencies: - inherits: "npm:^2.0.3" - string_decoder: "npm:^1.1.1" - util-deprecate: "npm:^1.0.1" - checksum: 10c0/e37be5c79c376fdd088a45fa31ea2e423e5d48854be7a22a58869b4e84d25047b193f6acb54f1012331e1bcd667ffb569c01b99d36b0bd59658fb33f513511b7 - languageName: node - linkType: hard - -"require-directory@npm:^2.1.1": - version: 2.1.1 - resolution: "require-directory@npm:2.1.1" - checksum: 10c0/83aa76a7bc1531f68d92c75a2ca2f54f1b01463cb566cf3fbc787d0de8be30c9dbc211d1d46be3497dac5785fe296f2dd11d531945ac29730643357978966e99 - languageName: node - linkType: hard - -"resolve-cwd@npm:^3.0.0": - version: 3.0.0 - resolution: "resolve-cwd@npm:3.0.0" - dependencies: - resolve-from: "npm:^5.0.0" - checksum: 10c0/e608a3ebd15356264653c32d7ecbc8fd702f94c6703ea4ac2fb81d9c359180cba0ae2e6b71faa446631ed6145454d5a56b227efc33a2d40638ac13f8beb20ee4 - languageName: node - linkType: hard - -"resolve-from@npm:^5.0.0": - version: 5.0.0 - resolution: "resolve-from@npm:5.0.0" - checksum: 10c0/b21cb7f1fb746de8107b9febab60095187781137fd803e6a59a76d421444b1531b641bba5857f5dc011974d8a5c635d61cec49e6bd3b7fc20e01f0fafc4efbf2 +"react-is@npm:^17.0.1": + version: 17.0.2 + resolution: "react-is@npm:17.0.2" + checksum: 10c0/2bdb6b93fbb1820b024b496042cce405c57e2f85e777c9aabd55f9b26d145408f9f74f5934676ffdc46f3dcff656d78413a6e43968e7b3f92eea35b3052e9053 languageName: node linkType: hard @@ -2768,28 +2654,89 @@ __metadata: languageName: node linkType: hard -"reusify@npm:^1.0.4": - version: 1.1.0 - resolution: "reusify@npm:1.1.0" - checksum: 10c0/4eff0d4a5f9383566c7d7ec437b671cc51b25963bd61bf127c3f3d3f68e44a026d99b8d2f1ad344afff8d278a8fe70a8ea092650a716d22287e8bef7126bb2fa - languageName: node - linkType: hard - -"run-parallel@npm:^1.1.9": - version: 1.2.0 - resolution: "run-parallel@npm:1.2.0" +"rollup@npm:^4.43.0": + version: 4.50.1 + resolution: "rollup@npm:4.50.1" dependencies: - queue-microtask: "npm:^1.2.2" - checksum: 10c0/200b5ab25b5b8b7113f9901bfe3afc347e19bb7475b267d55ad0eb86a62a46d77510cb0f232507c9e5d497ebda569a08a9867d0d14f57a82ad5564d991588b39 + "@rollup/rollup-android-arm-eabi": "npm:4.50.1" + "@rollup/rollup-android-arm64": "npm:4.50.1" + "@rollup/rollup-darwin-arm64": "npm:4.50.1" + "@rollup/rollup-darwin-x64": "npm:4.50.1" + "@rollup/rollup-freebsd-arm64": "npm:4.50.1" + "@rollup/rollup-freebsd-x64": "npm:4.50.1" + "@rollup/rollup-linux-arm-gnueabihf": "npm:4.50.1" + "@rollup/rollup-linux-arm-musleabihf": "npm:4.50.1" + "@rollup/rollup-linux-arm64-gnu": "npm:4.50.1" + "@rollup/rollup-linux-arm64-musl": "npm:4.50.1" + "@rollup/rollup-linux-loongarch64-gnu": "npm:4.50.1" + "@rollup/rollup-linux-ppc64-gnu": "npm:4.50.1" + "@rollup/rollup-linux-riscv64-gnu": "npm:4.50.1" + "@rollup/rollup-linux-riscv64-musl": "npm:4.50.1" + "@rollup/rollup-linux-s390x-gnu": "npm:4.50.1" + "@rollup/rollup-linux-x64-gnu": "npm:4.50.1" + "@rollup/rollup-linux-x64-musl": "npm:4.50.1" + "@rollup/rollup-openharmony-arm64": "npm:4.50.1" + "@rollup/rollup-win32-arm64-msvc": "npm:4.50.1" + "@rollup/rollup-win32-ia32-msvc": "npm:4.50.1" + "@rollup/rollup-win32-x64-msvc": "npm:4.50.1" + "@types/estree": "npm:1.0.8" + fsevents: "npm:~2.3.2" + dependenciesMeta: + "@rollup/rollup-android-arm-eabi": + optional: true + "@rollup/rollup-android-arm64": + optional: true + "@rollup/rollup-darwin-arm64": + optional: true + "@rollup/rollup-darwin-x64": + optional: true + "@rollup/rollup-freebsd-arm64": + optional: true + "@rollup/rollup-freebsd-x64": + optional: true + "@rollup/rollup-linux-arm-gnueabihf": + optional: true + "@rollup/rollup-linux-arm-musleabihf": + optional: true + "@rollup/rollup-linux-arm64-gnu": + optional: true + "@rollup/rollup-linux-arm64-musl": + optional: true + "@rollup/rollup-linux-loongarch64-gnu": + optional: true + "@rollup/rollup-linux-ppc64-gnu": + optional: true + "@rollup/rollup-linux-riscv64-gnu": + optional: true + "@rollup/rollup-linux-riscv64-musl": + optional: true + "@rollup/rollup-linux-s390x-gnu": + optional: true + "@rollup/rollup-linux-x64-gnu": + optional: true + "@rollup/rollup-linux-x64-musl": + optional: true + "@rollup/rollup-openharmony-arm64": + optional: true + "@rollup/rollup-win32-arm64-msvc": + optional: true + "@rollup/rollup-win32-ia32-msvc": + optional: true + "@rollup/rollup-win32-x64-msvc": + optional: true + fsevents: + optional: true + bin: + rollup: dist/bin/rollup + checksum: 10c0/2029282826d5fb4e308be261b2c28329a4d2bd34304cc3960da69fd21d5acccd0267d6770b1656ffc8f166203ef7e865b4583d5f842a519c8ef059ac71854205 languageName: node linkType: hard -"safe-buffer@npm:^5.0.1, safe-buffer@npm:~5.2.0": - version: 5.2.1 - resolution: "safe-buffer@npm:5.2.1" - checksum: 10c0/6501914237c0a86e9675d4e51d89ca3c21ffd6a31642efeba25ad65720bce6921c9e7e974e5be91a786b25aa058b5303285d3c15dbabf983a919f5f630d349f3 - languageName: node - linkType: hard +"root-workspace-0b6124@workspace:.": + version: 0.0.0-use.local + resolution: "root-workspace-0b6124@workspace:." + languageName: unknown + linkType: soft "safer-buffer@npm:>= 2.1.2 < 3, safer-buffer@npm:>= 2.1.2 < 3.0.0": version: 2.1.2 @@ -2798,7 +2745,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.3.2, semver@npm:^7.3.5, semver@npm:^7.5.3, semver@npm:^7.7.1": +"semver@npm:^7.3.5, semver@npm:^7.7.1": version: 7.7.2 resolution: "semver@npm:7.7.2" bin: @@ -2807,15 +2754,6 @@ __metadata: languageName: node linkType: hard -"serialize-error@npm:^7.0.1": - version: 7.0.1 - resolution: "serialize-error@npm:7.0.1" - dependencies: - type-fest: "npm:^0.13.1" - checksum: 10c0/7982937d578cd901276c8ab3e2c6ed8a4c174137730f1fb0402d005af209a0e84d04acc874e317c936724c7b5b26c7a96ff7e4b8d11a469f4924a4b0ea814c05 - languageName: node - linkType: hard - "shebang-command@npm:^2.0.0": version: 2.0.0 resolution: "shebang-command@npm:2.0.0" @@ -2832,6 +2770,13 @@ __metadata: languageName: node linkType: hard +"siginfo@npm:^2.0.0": + version: 2.0.0 + resolution: "siginfo@npm:2.0.0" + checksum: 10c0/3def8f8e516fbb34cb6ae415b07ccc5d9c018d85b4b8611e3dc6f8be6d1899f693a4382913c9ed51a06babb5201639d76453ab297d1c54a456544acf5c892e34 + languageName: node + linkType: hard + "signal-exit@npm:^4.0.1, signal-exit@npm:^4.1.0": version: 4.1.0 resolution: "signal-exit@npm:4.1.0" @@ -2839,38 +2784,14 @@ __metadata: languageName: node linkType: hard -"simple-concat@npm:^1.0.0": - version: 1.0.1 - resolution: "simple-concat@npm:1.0.1" - checksum: 10c0/62f7508e674414008910b5397c1811941d457dfa0db4fd5aa7fa0409eb02c3609608dfcd7508cace75b3a0bf67a2a77990711e32cd213d2c76f4fd12ee86d776 - languageName: node - linkType: hard - -"simple-get@npm:^4.0.0": - version: 4.0.1 - resolution: "simple-get@npm:4.0.1" +"sirv@npm:^3.0.1": + version: 3.0.2 + resolution: "sirv@npm:3.0.2" dependencies: - decompress-response: "npm:^6.0.0" - once: "npm:^1.3.1" - simple-concat: "npm:^1.0.0" - checksum: 10c0/b0649a581dbca741babb960423248899203165769747142033479a7dc5e77d7b0fced0253c731cd57cf21e31e4d77c9157c3069f4448d558ebc96cf9e1eebcf0 - languageName: node - linkType: hard - -"slash@npm:^5.1.0": - version: 5.1.0 - resolution: "slash@npm:5.1.0" - checksum: 10c0/eb48b815caf0bdc390d0519d41b9e0556a14380f6799c72ba35caf03544d501d18befdeeef074bc9c052acf69654bc9e0d79d7f1de0866284137a40805299eb3 - languageName: node - linkType: hard - -"slice-ansi@npm:^5.0.0": - version: 5.0.0 - resolution: "slice-ansi@npm:5.0.0" - dependencies: - ansi-styles: "npm:^6.0.0" - is-fullwidth-code-point: "npm:^4.0.0" - checksum: 10c0/2d4d40b2a9d5cf4e8caae3f698fe24ae31a4d778701724f578e984dcb485ec8c49f0c04dab59c401821e80fcdfe89cace9c66693b0244e40ec485d72e543914f + "@polka/url": "npm:^1.0.0-next.24" + mrmime: "npm:^2.0.0" + totalist: "npm:^3.0.0" + checksum: 10c0/5930e4397afdb14fbae13751c3be983af4bda5c9aadec832607dc2af15a7162f7d518c71b30e83ae3644b9a24cea041543cc969e5fe2b80af6ce8ea3174b2d04 languageName: node linkType: hard @@ -2893,26 +2814,19 @@ __metadata: linkType: hard "socks@npm:^2.8.3": - version: 2.8.6 - resolution: "socks@npm:2.8.6" + version: 2.8.7 + resolution: "socks@npm:2.8.7" dependencies: - ip-address: "npm:^9.0.5" + ip-address: "npm:^10.0.1" smart-buffer: "npm:^4.2.0" - checksum: 10c0/15b95db4caa359c80bfa880ff3e58f3191b9ffa4313570e501a60ee7575f51e4be664a296f4ee5c2c40544da179db6140be53433ce41ec745f9d51f342557514 + checksum: 10c0/2805a43a1c4bcf9ebf6e018268d87b32b32b06fbbc1f9282573583acc155860dc361500f89c73bfbb157caa1b4ac78059eac0ef15d1811eb0ca75e0bdadbc9d2 languageName: node linkType: hard -"sprintf-js@npm:^1.1.3": - version: 1.1.3 - resolution: "sprintf-js@npm:1.1.3" - checksum: 10c0/09270dc4f30d479e666aee820eacd9e464215cdff53848b443964202bf4051490538e5dd1b42e1a65cf7296916ca17640aebf63dae9812749c7542ee5f288dec - languageName: node - linkType: hard - -"sprintf-js@npm:~1.0.2": - version: 1.0.3 - resolution: "sprintf-js@npm:1.0.3" - checksum: 10c0/ecadcfe4c771890140da5023d43e190b7566d9cf8b2d238600f31bec0fc653f328da4450eb04bd59a431771a8e9cc0e118f0aa3974b683a4981b4e07abc2a5bb +"source-map-js@npm:^1.2.1": + version: 1.2.1 + resolution: "source-map-js@npm:1.2.1" + checksum: 10c0/7bda1fc4c197e3c6ff17de1b8b2c20e60af81b63a52cb32ec5a5d67a20a7d42651e2cb34ebe93833c5a2a084377e17455854fee3e21e7925c64a51b6a52b0faf languageName: node linkType: hard @@ -2925,16 +2839,21 @@ __metadata: languageName: node linkType: hard -"stack-utils@npm:^2.0.6": - version: 2.0.6 - resolution: "stack-utils@npm:2.0.6" - dependencies: - escape-string-regexp: "npm:^2.0.0" - checksum: 10c0/651c9f87667e077584bbe848acaecc6049bc71979f1e9a46c7b920cad4431c388df0f51b8ad7cfd6eed3db97a2878d0fc8b3122979439ea8bac29c61c95eec8a +"stackback@npm:0.0.2": + version: 0.0.2 + resolution: "stackback@npm:0.0.2" + checksum: 10c0/89a1416668f950236dd5ac9f9a6b2588e1b9b62b1b6ad8dff1bfc5d1a15dbf0aafc9b52d2226d00c28dffff212da464eaeebfc6b7578b9d180cef3e3782c5983 languageName: node linkType: hard -"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.3": +"std-env@npm:^3.9.0": + version: 3.9.0 + resolution: "std-env@npm:3.9.0" + checksum: 10c0/4a6f9218aef3f41046c3c7ecf1f98df00b30a07f4f35c6d47b28329bc2531eef820828951c7d7b39a1c5eb19ad8a46e3ddfc7deb28f0a2f3ceebee11bab7ba50 + languageName: node + linkType: hard + +"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^4.1.0": version: 4.2.3 resolution: "string-width@npm:4.2.3" dependencies: @@ -2956,26 +2875,6 @@ __metadata: languageName: node linkType: hard -"string-width@npm:^7.0.0": - version: 7.2.0 - resolution: "string-width@npm:7.2.0" - dependencies: - emoji-regex: "npm:^10.3.0" - get-east-asian-width: "npm:^1.0.0" - strip-ansi: "npm:^7.1.0" - checksum: 10c0/eb0430dd43f3199c7a46dcbf7a0b34539c76fe3aa62763d0b0655acdcbdf360b3f66f3d58ca25ba0205f42ea3491fa00f09426d3b7d3040e506878fc7664c9b9 - languageName: node - linkType: hard - -"string_decoder@npm:^1.1.1": - version: 1.3.0 - resolution: "string_decoder@npm:1.3.0" - dependencies: - safe-buffer: "npm:~5.2.0" - checksum: 10c0/810614ddb030e271cd591935dcd5956b2410dd079d64ff92a1844d6b7588bf992b3e1b69b0f4d34a3e06e0bd73046ac646b5264c1987b20d0601f81ef35d731d - languageName: node - linkType: hard - "strip-ansi-cjs@npm:strip-ansi@^6.0.1, strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": version: 6.0.1 resolution: "strip-ansi@npm:6.0.1" @@ -2985,60 +2884,25 @@ __metadata: languageName: node linkType: hard -"strip-ansi@npm:^7.0.1, strip-ansi@npm:^7.1.0": - version: 7.1.0 - resolution: "strip-ansi@npm:7.1.0" +"strip-ansi@npm:^7.0.1": + version: 7.1.2 + resolution: "strip-ansi@npm:7.1.2" dependencies: ansi-regex: "npm:^6.0.1" - checksum: 10c0/a198c3762e8832505328cbf9e8c8381de14a4fa50a4f9b2160138158ea88c0f5549fb50cb13c651c3088f47e63a108b34622ec18c0499b6c8c3a5ddf6b305ac4 + checksum: 10c0/0d6d7a023de33368fd042aab0bf48f4f4077abdfd60e5393e73c7c411e85e1b3a83507c11af2e656188511475776215df9ca589b4da2295c9455cc399ce1858b languageName: node linkType: hard -"strip-json-comments@npm:~2.0.1": - version: 2.0.1 - resolution: "strip-json-comments@npm:2.0.1" - checksum: 10c0/b509231cbdee45064ff4f9fd73609e2bcc4e84a4d508e9dd0f31f70356473fde18abfb5838c17d56fb236f5a06b102ef115438de0600b749e818a35fbbc48c43 - languageName: node - linkType: hard - -"supertap@npm:^3.0.1": - version: 3.0.1 - resolution: "supertap@npm:3.0.1" +"strip-literal@npm:^3.0.0": + version: 3.0.0 + resolution: "strip-literal@npm:3.0.0" dependencies: - indent-string: "npm:^5.0.0" - js-yaml: "npm:^3.14.1" - serialize-error: "npm:^7.0.1" - strip-ansi: "npm:^7.0.1" - checksum: 10c0/8164674f2e280cab875f0fef5bb36c15553c13e29697ff92f4e0d6bc62149f0303a89eee47535413ed145ea72e14a24d065bab233059d48a499ec5ebb4566b0f + js-tokens: "npm:^9.0.1" + checksum: 10c0/d81657f84aba42d4bbaf2a677f7e7f34c1f3de5a6726db8bc1797f9c0b303ba54d4660383a74bde43df401cf37cce1dff2c842c55b077a4ceee11f9e31fba828 languageName: node linkType: hard -"tar-fs@npm:^2.0.0": - version: 2.1.3 - resolution: "tar-fs@npm:2.1.3" - dependencies: - chownr: "npm:^1.1.1" - mkdirp-classic: "npm:^0.5.2" - pump: "npm:^3.0.0" - tar-stream: "npm:^2.1.4" - checksum: 10c0/472ee0c3c862605165163113ab6924f411c07506a1fb24c51a1a80085f0d4d381d86d2fd6b189236c8d932d1cd97b69cce35016767ceb658a35f7584fe77f305 - languageName: node - linkType: hard - -"tar-stream@npm:^2.1.4": - version: 2.2.0 - resolution: "tar-stream@npm:2.2.0" - dependencies: - bl: "npm:^4.0.3" - end-of-stream: "npm:^1.4.1" - fs-constants: "npm:^1.0.0" - inherits: "npm:^2.0.3" - readable-stream: "npm:^3.1.1" - checksum: 10c0/2f4c910b3ee7196502e1ff015a7ba321ec6ea837667220d7bcb8d0852d51cb04b87f7ae471008a6fb8f5b1a1b5078f62f3a82d30c706f20ada1238ac797e7692 - languageName: node - linkType: hard - -"tar@npm:^7.4.0, tar@npm:^7.4.3": +"tar@npm:^7.4.3": version: 7.4.3 resolution: "tar@npm:7.4.3" dependencies: @@ -3052,27 +2916,48 @@ __metadata: languageName: node linkType: hard -"temp-dir@npm:^3.0.0": - version: 3.0.0 - resolution: "temp-dir@npm:3.0.0" - checksum: 10c0/a86978a400984cd5f315b77ebf3fe53bb58c61f192278cafcb1f3fb32d584a21dc8e08b93171d7874b7cc972234d3455c467306cc1bfc4524b622e5ad3bfd671 +"tinybench@npm:^2.9.0": + version: 2.9.0 + resolution: "tinybench@npm:2.9.0" + checksum: 10c0/c3500b0f60d2eb8db65250afe750b66d51623057ee88720b7f064894a6cb7eb93360ca824a60a31ab16dab30c7b1f06efe0795b352e37914a9d4bad86386a20c languageName: node linkType: hard -"time-zone@npm:^1.0.0": - version: 1.0.0 - resolution: "time-zone@npm:1.0.0" - checksum: 10c0/d00ebd885039109011b6e2423ebbf225160927333c2ade6d833e9cc4676db20759f1f3855fafde00d1bd668c243a6aa68938ce71fe58aab0d514e820d59c1d81 +"tinyexec@npm:^0.3.2": + version: 0.3.2 + resolution: "tinyexec@npm:0.3.2" + checksum: 10c0/3efbf791a911be0bf0821eab37a3445c2ba07acc1522b1fa84ae1e55f10425076f1290f680286345ed919549ad67527d07281f1c19d584df3b74326909eb1f90 languageName: node linkType: hard -"tinyglobby@npm:^0.2.12": - version: 0.2.14 - resolution: "tinyglobby@npm:0.2.14" +"tinyglobby@npm:^0.2.12, tinyglobby@npm:^0.2.14, tinyglobby@npm:^0.2.15": + version: 0.2.15 + resolution: "tinyglobby@npm:0.2.15" dependencies: - fdir: "npm:^6.4.4" - picomatch: "npm:^4.0.2" - checksum: 10c0/f789ed6c924287a9b7d3612056ed0cda67306cd2c80c249fd280cf1504742b12583a2089b61f4abbd24605f390809017240e250241f09938054c9b363e51c0a6 + fdir: "npm:^6.5.0" + picomatch: "npm:^4.0.3" + checksum: 10c0/869c31490d0d88eedb8305d178d4c75e7463e820df5a9b9d388291daf93e8b1eb5de1dad1c1e139767e4269fe75f3b10d5009b2cc14db96ff98986920a186844 + languageName: node + linkType: hard + +"tinypool@npm:^1.1.1": + version: 1.1.1 + resolution: "tinypool@npm:1.1.1" + checksum: 10c0/bf26727d01443061b04fa863f571016950888ea994ba0cd8cba3a1c51e2458d84574341ab8dbc3664f1c3ab20885c8cf9ff1cc4b18201f04c2cde7d317fff69b + languageName: node + linkType: hard + +"tinyrainbow@npm:^2.0.0": + version: 2.0.0 + resolution: "tinyrainbow@npm:2.0.0" + checksum: 10c0/c83c52bef4e0ae7fb8ec6a722f70b5b6fa8d8be1c85792e829f56c0e1be94ab70b293c032dc5048d4d37cfe678f1f5babb04bdc65fd123098800148ca989184f + languageName: node + linkType: hard + +"tinyspy@npm:^4.0.3": + version: 4.0.3 + resolution: "tinyspy@npm:4.0.3" + checksum: 10c0/0a92a18b5350945cc8a1da3a22c9ad9f4e2945df80aaa0c43e1b3a3cfb64d8501e607ebf0305e048e3c3d3e0e7f8eb10cea27dc17c21effb73e66c4a3be36373 languageName: node linkType: hard @@ -3085,19 +2970,10 @@ __metadata: languageName: node linkType: hard -"to-regex-range@npm:^5.0.1": - version: 5.0.1 - resolution: "to-regex-range@npm:5.0.1" - dependencies: - is-number: "npm:^7.0.0" - checksum: 10c0/487988b0a19c654ff3e1961b87f471702e708fa8a8dd02a298ef16da7206692e8552a0250e8b3e8759270f62e9d8314616f6da274734d3b558b1fc7b7724e892 - languageName: node - linkType: hard - -"tr46@npm:~0.0.3": - version: 0.0.3 - resolution: "tr46@npm:0.0.3" - checksum: 10c0/047cb209a6b60c742f05c9d3ace8fa510bff609995c129a37ace03476a9b12db4dbf975e74600830ef0796e18882b2381fb5fb1f6b4f96b832c374de3ab91a11 +"totalist@npm:^3.0.0": + version: 3.0.1 + resolution: "totalist@npm:3.0.1" + checksum: 10c0/4bb1fadb69c3edbef91c73ebef9d25b33bbf69afe1e37ce544d5f7d13854cda15e47132f3e0dc4cafe300ddb8578c77c50a65004d8b6e97e77934a69aa924863 languageName: node linkType: hard @@ -3108,15 +2984,6 @@ __metadata: languageName: node linkType: hard -"tunnel-agent@npm:^0.6.0": - version: 0.6.0 - resolution: "tunnel-agent@npm:0.6.0" - dependencies: - safe-buffer: "npm:^5.0.1" - checksum: 10c0/4c7a1b813e7beae66fdbf567a65ec6d46313643753d0beefb3c7973d66fcec3a1e7f39759f0a0b4465883499c6dc8b0750ab8b287399af2e583823e40410a17a - languageName: node - linkType: hard - "typanion@npm:^3.14.0, typanion@npm:^3.8.0": version: 3.14.0 resolution: "typanion@npm:3.14.0" @@ -3124,13 +2991,6 @@ __metadata: languageName: node linkType: hard -"type-fest@npm:^0.13.1": - version: 0.13.1 - resolution: "type-fest@npm:0.13.1" - checksum: 10c0/0c0fa07ae53d4e776cf4dac30d25ad799443e9eef9226f9fddbb69242db86b08584084a99885cfa5a9dfe4c063ebdc9aa7b69da348e735baede8d43f1aeae93b - languageName: node - linkType: hard - "type-fest@npm:^0.21.3": version: 0.21.3 resolution: "type-fest@npm:0.21.3" @@ -3158,6 +3018,13 @@ __metadata: languageName: node linkType: hard +"undici-types@npm:~7.10.0": + version: 7.10.0 + resolution: "undici-types@npm:7.10.0" + checksum: 10c0/8b00ce50e235fe3cc601307f148b5e8fb427092ee3b23e8118ec0a5d7f68eca8cee468c8fc9f15cbb2cf2a3797945ebceb1cbd9732306a1d00e0a9b6afa0f635 + languageName: node + linkType: hard + "unicorn-magic@npm:^0.1.0": version: 0.1.0 resolution: "unicorn-magic@npm:0.1.0" @@ -3165,13 +3032,6 @@ __metadata: languageName: node linkType: hard -"unicorn-magic@npm:^0.3.0": - version: 0.3.0 - resolution: "unicorn-magic@npm:0.3.0" - checksum: 10c0/0a32a997d6c15f1c2a077a15b1c4ca6f268d574cf5b8975e778bb98e6f8db4ef4e86dfcae4e158cd4c7e38fb4dd383b93b13eefddc7f178dea13d3ac8a603271 - languageName: node - linkType: hard - "unique-filename@npm:^4.0.0": version: 4.0.0 resolution: "unique-filename@npm:4.0.0" @@ -3197,34 +3057,129 @@ __metadata: languageName: node linkType: hard -"util-deprecate@npm:^1.0.1": - version: 1.0.2 - resolution: "util-deprecate@npm:1.0.2" - checksum: 10c0/41a5bdd214df2f6c3ecf8622745e4a366c4adced864bc3c833739791aeeeb1838119af7daed4ba36428114b5c67dcda034a79c882e97e43c03e66a4dd7389942 - languageName: node - linkType: hard - -"webidl-conversions@npm:^3.0.0": - version: 3.0.1 - resolution: "webidl-conversions@npm:3.0.1" - checksum: 10c0/5612d5f3e54760a797052eb4927f0ddc01383550f542ccd33d5238cfd65aeed392a45ad38364970d0a0f4fea32e1f4d231b3d8dac4a3bdd385e5cf802ae097db - languageName: node - linkType: hard - -"well-known-symbols@npm:^2.0.0": - version: 2.0.0 - resolution: "well-known-symbols@npm:2.0.0" - checksum: 10c0/cb6c12e98877e8952ec28d13ae6f4fdb54ae1cb49b16a728720276dadd76c930e6cb0e174af3a4620054dd2752546f842540122920c6e31410208abd4958ee6b - languageName: node - linkType: hard - -"whatwg-url@npm:^5.0.0": - version: 5.0.0 - resolution: "whatwg-url@npm:5.0.0" +"vite-node@npm:3.2.4": + version: 3.2.4 + resolution: "vite-node@npm:3.2.4" dependencies: - tr46: "npm:~0.0.3" - webidl-conversions: "npm:^3.0.0" - checksum: 10c0/1588bed84d10b72d5eec1d0faa0722ba1962f1821e7539c535558fb5398d223b0c50d8acab950b8c488b4ba69043fd833cc2697056b167d8ad46fac3995a55d5 + cac: "npm:^6.7.14" + debug: "npm:^4.4.1" + es-module-lexer: "npm:^1.7.0" + pathe: "npm:^2.0.3" + vite: "npm:^5.0.0 || ^6.0.0 || ^7.0.0-0" + bin: + vite-node: vite-node.mjs + checksum: 10c0/6ceca67c002f8ef6397d58b9539f80f2b5d79e103a18367288b3f00a8ab55affa3d711d86d9112fce5a7fa658a212a087a005a045eb8f4758947dd99af2a6c6b + languageName: node + linkType: hard + +"vite@npm:^5.0.0 || ^6.0.0 || ^7.0.0-0": + version: 7.1.5 + resolution: "vite@npm:7.1.5" + dependencies: + esbuild: "npm:^0.25.0" + fdir: "npm:^6.5.0" + fsevents: "npm:~2.3.3" + picomatch: "npm:^4.0.3" + postcss: "npm:^8.5.6" + rollup: "npm:^4.43.0" + tinyglobby: "npm:^0.2.15" + peerDependencies: + "@types/node": ^20.19.0 || >=22.12.0 + jiti: ">=1.21.0" + less: ^4.0.0 + lightningcss: ^1.21.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: ">=0.54.8" + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + dependenciesMeta: + fsevents: + optional: true + peerDependenciesMeta: + "@types/node": + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + bin: + vite: bin/vite.js + checksum: 10c0/782d2f20c25541b26d1fb39bef5f194149caff39dc25b7836e25f049ca919f2e2ce186bddb21f3f20f6195354b3579ec637a8ca08d65b117f8b6f81e3e730a9c + languageName: node + linkType: hard + +"vitest@npm:^3.2.4": + version: 3.2.4 + resolution: "vitest@npm:3.2.4" + dependencies: + "@types/chai": "npm:^5.2.2" + "@vitest/expect": "npm:3.2.4" + "@vitest/mocker": "npm:3.2.4" + "@vitest/pretty-format": "npm:^3.2.4" + "@vitest/runner": "npm:3.2.4" + "@vitest/snapshot": "npm:3.2.4" + "@vitest/spy": "npm:3.2.4" + "@vitest/utils": "npm:3.2.4" + chai: "npm:^5.2.0" + debug: "npm:^4.4.1" + expect-type: "npm:^1.2.1" + magic-string: "npm:^0.30.17" + pathe: "npm:^2.0.3" + picomatch: "npm:^4.0.2" + std-env: "npm:^3.9.0" + tinybench: "npm:^2.9.0" + tinyexec: "npm:^0.3.2" + tinyglobby: "npm:^0.2.14" + tinypool: "npm:^1.1.1" + tinyrainbow: "npm:^2.0.0" + vite: "npm:^5.0.0 || ^6.0.0 || ^7.0.0-0" + vite-node: "npm:3.2.4" + why-is-node-running: "npm:^2.3.0" + peerDependencies: + "@edge-runtime/vm": "*" + "@types/debug": ^4.1.12 + "@types/node": ^18.0.0 || ^20.0.0 || >=22.0.0 + "@vitest/browser": 3.2.4 + "@vitest/ui": 3.2.4 + happy-dom: "*" + jsdom: "*" + peerDependenciesMeta: + "@edge-runtime/vm": + optional: true + "@types/debug": + optional: true + "@types/node": + optional: true + "@vitest/browser": + optional: true + "@vitest/ui": + optional: true + happy-dom: + optional: true + jsdom: + optional: true + bin: + vitest: vitest.mjs + checksum: 10c0/5bf53ede3ae6a0e08956d72dab279ae90503f6b5a05298a6a5e6ef47d2fd1ab386aaf48fafa61ed07a0ebfe9e371772f1ccbe5c258dd765206a8218bf2eb79eb languageName: node linkType: hard @@ -3250,7 +3205,19 @@ __metadata: languageName: node linkType: hard -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0, wrap-ansi@npm:^7.0.0": +"why-is-node-running@npm:^2.3.0": + version: 2.3.0 + resolution: "why-is-node-running@npm:2.3.0" + dependencies: + siginfo: "npm:^2.0.0" + stackback: "npm:0.0.2" + bin: + why-is-node-running: cli.js + checksum: 10c0/1cde0b01b827d2cf4cb11db962f3958b9175d5d9e7ac7361d1a7b0e2dc6069a263e69118bd974c4f6d0a890ef4eedfe34cf3d5167ec14203dbc9a18620537054 + languageName: node + linkType: hard + +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": version: 7.0.0 resolution: "wrap-ansi@npm:7.0.0" dependencies: @@ -3283,27 +3250,18 @@ __metadata: languageName: node linkType: hard -"wrappy@npm:1": - version: 1.0.2 - resolution: "wrappy@npm:1.0.2" - checksum: 10c0/56fece1a4018c6a6c8e28fbc88c87e0fbf4ea8fd64fc6c63b18f4acc4bd13e0ad2515189786dd2c30d3eec9663d70f4ecf699330002f8ccb547e4a18231fc9f0 - languageName: node - linkType: hard - -"write-file-atomic@npm:^6.0.0": - version: 6.0.0 - resolution: "write-file-atomic@npm:6.0.0" - dependencies: - imurmurhash: "npm:^0.1.4" - signal-exit: "npm:^4.0.1" - checksum: 10c0/ae2f1c27474758a9aca92037df6c1dd9cb94c4e4983451210bd686bfe341f142662f6aa5913095e572ab037df66b1bfe661ed4ce4c0369ed0e8219e28e141786 - languageName: node - linkType: hard - -"y18n@npm:^5.0.5": - version: 5.0.8 - resolution: "y18n@npm:5.0.8" - checksum: 10c0/4df2842c36e468590c3691c894bc9cdbac41f520566e76e24f59401ba7d8b4811eb1e34524d57e54bc6d864bcb66baab7ffd9ca42bf1eda596618f9162b91249 +"ws@npm:^8.18.2": + version: 8.18.3 + resolution: "ws@npm:8.18.3" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ">=5.0.2" + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: 10c0/eac918213de265ef7cb3d4ca348b891a51a520d839aa51cdb8ca93d4fa7ff9f6ccb339ccee89e4075324097f0a55157c89fa3f7147bde9d8d7e90335dc087b53 languageName: node linkType: hard @@ -3321,28 +3279,6 @@ __metadata: languageName: node linkType: hard -"yargs-parser@npm:^21.1.1": - version: 21.1.1 - resolution: "yargs-parser@npm:21.1.1" - checksum: 10c0/f84b5e48169479d2f402239c59f084cfd1c3acc197a05c59b98bab067452e6b3ea46d4dd8ba2985ba7b3d32a343d77df0debd6b343e5dae3da2aab2cdf5886b2 - languageName: node - linkType: hard - -"yargs@npm:^17.7.2": - version: 17.7.2 - resolution: "yargs@npm:17.7.2" - dependencies: - cliui: "npm:^8.0.1" - escalade: "npm:^3.1.1" - get-caller-file: "npm:^2.0.5" - require-directory: "npm:^2.1.1" - string-width: "npm:^4.2.3" - y18n: "npm:^5.0.5" - yargs-parser: "npm:^21.1.1" - checksum: 10c0/ccd7e723e61ad5965fffbb791366db689572b80cca80e0f96aad968dfff4156cd7cd1ad18607afe1046d8241e6fb2d6c08bf7fa7bfb5eaec818735d8feac8f05 - languageName: node - linkType: hard - "yocto-queue@npm:^1.0.0": version: 1.2.1 resolution: "yocto-queue@npm:1.2.1" diff --git a/cli/app.rs b/cli/app.rs index d1dcefa70..298891f38 100644 --- a/cli/app.rs +++ b/cli/app.rs @@ -94,6 +94,60 @@ struct QueryStatistics { execute_time_elapsed_samples: Vec, } +macro_rules! row_step_result_query { + ($app:expr, $sql:expr, $rows:expr, $stats:expr, $row_handle:expr) => { + if $app.interrupt_count.load(Ordering::Acquire) > 0 { + println!("Query interrupted."); + return Ok(()); + } + + let start = Instant::now(); + match $rows.step() { + Ok(StepResult::Row) => { + if let Some(ref mut stats) = $stats { + stats.execute_time_elapsed_samples.push(start.elapsed()); + } + + $row_handle + } + Ok(StepResult::IO) => { + let start = Instant::now(); + $rows.run_once()?; + if let Some(ref mut stats) = $stats { + stats.io_time_elapsed_samples.push(start.elapsed()); + } + } + Ok(StepResult::Interrupt) => { + if let Some(ref mut stats) = $stats { + stats.execute_time_elapsed_samples.push(start.elapsed()); + } + break; + } + Ok(StepResult::Done) => { + if let Some(ref mut stats) = $stats { + stats.execute_time_elapsed_samples.push(start.elapsed()); + } + break; + } + Ok(StepResult::Busy) => { + if let Some(ref mut stats) = $stats { + stats.execute_time_elapsed_samples.push(start.elapsed()); + } + let _ = $app.writeln("database is busy"); + break; + } + Err(err) => { + if let Some(ref mut stats) = $stats { + stats.execute_time_elapsed_samples.push(start.elapsed()); + } + let report = miette::Error::from(err).with_source_code($sql.to_owned()); + let _ = $app.writeln_fmt(format_args!("{report:?}")); + break; + } + } + }; +} + impl Limbo { pub fn new() -> anyhow::Result<(Self, WorkerGuard)> { let opts = Opts::parse(); @@ -192,7 +246,7 @@ impl Limbo { self.handle_first_input(&sql)?; } if !quiet { - self.write_fmt(format_args!("Turso v{}", env!("CARGO_PKG_VERSION")))?; + self.writeln_fmt(format_args!("Turso v{}", env!("CARGO_PKG_VERSION")))?; self.writeln("Enter \".help\" for usage hints.")?; self.writeln( "This software is ALPHA, only use for development, testing, and experimentation.", @@ -363,7 +417,11 @@ impl Limbo { } fn write_fmt(&mut self, fmt: std::fmt::Arguments) -> io::Result<()> { - let _ = self.writer.as_mut().unwrap().write_fmt(fmt); + self.writer.as_mut().unwrap().write_fmt(fmt) + } + + fn writeln_fmt(&mut self, fmt: std::fmt::Arguments) -> io::Result<()> { + self.writer.as_mut().unwrap().write_fmt(fmt)?; self.writer.as_mut().unwrap().write_all(b"\n") } @@ -376,6 +434,12 @@ impl Limbo { self.writer.as_mut().unwrap().write_all(b"\n") } + fn write_null(&mut self) -> io::Result<()> { + self.writer + .as_mut() + .unwrap() + .write_all(self.opts.null_value.as_bytes()) + } fn run_query(&mut self, input: &str) { let echo = self.opts.echo; if echo { @@ -383,9 +447,13 @@ impl Limbo { } let start = Instant::now(); - let mut stats = QueryStatistics { - io_time_elapsed_samples: vec![], - execute_time_elapsed_samples: vec![], + let mut stats = if self.opts.timer { + Some(QueryStatistics { + io_time_elapsed_samples: vec![], + execute_time_elapsed_samples: vec![], + }) + } else { + None }; // TODO this is a quickfix. Some ideas to do case insensitive comparisons is to use // Uncased or Unicase. @@ -410,14 +478,15 @@ impl Limbo { let runner = conn.query_runner(input.as_bytes()); for output in runner { if self - .print_query_result(input, output, Some(&mut stats)) + .print_query_result(input, output, stats.as_mut()) .is_err() { break; } } } - self.print_query_performance_stats(start, stats); + + self.print_query_performance_stats(start, stats.as_ref()); // Display stats if enabled if self.opts.stats { @@ -434,7 +503,7 @@ impl Limbo { } } - fn print_query_performance_stats(&mut self, start: Instant, stats: QueryStatistics) { + fn print_query_performance_stats(&mut self, start: Instant, stats: Option<&QueryStatistics>) { let elapsed_as_str = |duration: Duration| { if duration.as_secs() >= 1 { format!("{} s", duration.as_secs_f64()) @@ -446,7 +515,7 @@ impl Limbo { format!("{} ns", duration.as_nanos()) } }; - let sample_stats_as_str = |name: &str, samples: Vec| { + let sample_stats_as_str = |name: &str, samples: &Vec| { if samples.is_empty() { return format!("{name}: No samples available"); } @@ -460,18 +529,20 @@ impl Limbo { ) }; if self.opts.timer { - let _ = self.writeln("Command stats:\n----------------------------"); - let _ = self.writeln(format!( - "total: {} (this includes parsing/coloring of cli app)\n", - elapsed_as_str(start.elapsed()) - )); + if let Some(stats) = stats { + let _ = self.writeln("Command stats:\n----------------------------"); + let _ = self.writeln(format!( + "total: {} (this includes parsing/coloring of cli app)\n", + elapsed_as_str(start.elapsed()) + )); - let _ = self.writeln("query execution stats:\n----------------------------"); - let _ = self.writeln(sample_stats_as_str( - "Execution", - stats.execute_time_elapsed_samples, - )); - let _ = self.writeln(sample_stats_as_str("I/O", stats.io_time_elapsed_samples)); + let _ = self.writeln("query execution stats:\n----------------------------"); + let _ = self.writeln(sample_stats_as_str( + "Execution", + &stats.execute_time_elapsed_samples, + )); + let _ = self.writeln(sample_stats_as_str("I/O", &stats.io_time_elapsed_samples)); + } } } @@ -593,12 +664,12 @@ impl Limbo { if let Some(opcode) = args.opcode { for op in &OPCODE_DESCRIPTIONS { if op.name.eq_ignore_ascii_case(opcode.trim()) { - let _ = self.write_fmt(format_args!("{op}")); + let _ = self.writeln_fmt(format_args!("{op}")); } } } else { for op in &OPCODE_DESCRIPTIONS { - let _ = self.write_fmt(format_args!("{op}\n")); + let _ = self.writeln_fmt(format_args!("{op}\n")); } } } @@ -607,13 +678,13 @@ impl Limbo { } Command::OutputMode(args) => { if let Err(e) = self.set_mode(args.mode) { - let _ = self.write_fmt(format_args!("Error: {e}")); + let _ = self.writeln_fmt(format_args!("Error: {e}")); } } Command::SetOutput(args) => { if let Some(path) = args.path { if let Err(e) = self.set_output_file(&path) { - let _ = self.write_fmt(format_args!("Error: {e}")); + let _ = self.writeln_fmt(format_args!("Error: {e}")); } } else { self.set_output_stdout(); @@ -646,7 +717,7 @@ impl Limbo { } Command::Dump => { if let Err(e) = self.dump_database() { - let _ = self.write_fmt(format_args!("/****** ERROR: {e} ******/")); + let _ = self.writeln_fmt(format_args!("/****** ERROR: {e} ******/")); } } Command::DbConfig(_args) => { @@ -695,88 +766,35 @@ impl Limbo { OutputMode::List => { let mut headers_printed = false; loop { - if self.interrupt_count.load(Ordering::Acquire) > 0 { - println!("Query interrupted."); - return Ok(()); - } - - let start = Instant::now(); - - match rows.step() { - Ok(StepResult::Row) => { - if let Some(ref mut stats) = statistics { - stats.execute_time_elapsed_samples.push(start.elapsed()); - } - - // Print headers if enabled and not already printed - if self.opts.headers && !headers_printed { - for i in 0..rows.num_columns() { - if i > 0 { - let _ = self.write(b"|"); - } - let _ = self.write(rows.get_column_name(i).as_bytes()); - } - let _ = self.writeln(""); - headers_printed = true; - } - - let row = rows.row().unwrap(); - for (i, value) in row.get_values().enumerate() { + row_step_result_query!(self, sql, rows, statistics, { + // Print headers if enabled and not already printed + if self.opts.headers && !headers_printed { + for i in 0..rows.num_columns() { if i > 0 { let _ = self.write(b"|"); } - if matches!(value, Value::Null) { - let bytes = self.opts.null_value.clone(); - self.write(bytes.as_bytes())?; - } else { - self.write(format!("{value}").as_bytes())?; - } + let _ = self.write(rows.get_column_name(i).as_bytes()); } let _ = self.writeln(""); + headers_printed = true; } - Ok(StepResult::IO) => { - let start = Instant::now(); - rows.run_once()?; - if let Some(ref mut stats) = statistics { - stats.io_time_elapsed_samples.push(start.elapsed()); + + let row = rows.row().unwrap(); + for (i, value) in row.get_values().enumerate() { + if i > 0 { + let _ = self.write(b"|"); + } + if matches!(value, Value::Null) { + self.write_null()?; + } else { + write!(self, "{value}")?; } } - Ok(StepResult::Interrupt) => { - if let Some(ref mut stats) = statistics { - stats.execute_time_elapsed_samples.push(start.elapsed()); - } - break; - } - Ok(StepResult::Done) => { - if let Some(ref mut stats) = statistics { - stats.execute_time_elapsed_samples.push(start.elapsed()); - } - break; - } - Ok(StepResult::Busy) => { - if let Some(ref mut stats) = statistics { - stats.execute_time_elapsed_samples.push(start.elapsed()); - } - let _ = self.writeln("database is busy"); - break; - } - Err(err) => { - if let Some(ref mut stats) = statistics { - stats.execute_time_elapsed_samples.push(start.elapsed()); - } - let report = - miette::Error::from(err).with_source_code(sql.to_owned()); - let _ = self.write_fmt(format_args!("{report:?}")); - break; - } - } + let _ = self.writeln(""); + }); } } OutputMode::Pretty => { - if self.interrupt_count.load(Ordering::Acquire) > 0 { - println!("Query interrupted."); - return Ok(()); - } let config = self.config.as_ref().unwrap(); let mut table = Table::new(); table @@ -795,170 +813,76 @@ impl Limbo { table.set_header(header); } loop { - let start = Instant::now(); - match rows.step() { - Ok(StepResult::Row) => { - if let Some(ref mut stats) = statistics { - stats.execute_time_elapsed_samples.push(start.elapsed()); - } - let record = rows.row().unwrap(); - let mut row = Row::new(); - row.max_height(1); - for (idx, value) in record.get_values().enumerate() { - let (content, alignment) = match value { - Value::Null => { - (self.opts.null_value.clone(), CellAlignment::Left) - } - Value::Integer(_) => { - (format!("{value}"), CellAlignment::Right) - } - Value::Float(_) => { - (format!("{value}"), CellAlignment::Right) - } - Value::Text(_) => (format!("{value}"), CellAlignment::Left), - Value::Blob(_) => (format!("{value}"), CellAlignment::Left), - }; - row.add_cell( - Cell::new(content) - .set_alignment(alignment) - .fg(config.table.column_colors - [idx % config.table.column_colors.len()] - .as_comfy_table_color()), - ); - } - table.add_row(row); + row_step_result_query!(self, sql, rows, statistics, { + let record = rows.row().unwrap(); + let mut row = Row::new(); + row.max_height(1); + for (idx, value) in record.get_values().enumerate() { + let (content, alignment) = match value { + Value::Null => { + (self.opts.null_value.clone(), CellAlignment::Left) + } + Value::Integer(_) => (format!("{value}"), CellAlignment::Right), + Value::Float(_) => (format!("{value}"), CellAlignment::Right), + Value::Text(_) => (format!("{value}"), CellAlignment::Left), + Value::Blob(_) => (format!("{value}"), CellAlignment::Left), + }; + row.add_cell( + Cell::new(content) + .set_alignment(alignment) + .fg(config.table.column_colors + [idx % config.table.column_colors.len()] + .as_comfy_table_color()), + ); } - Ok(StepResult::IO) => { - let start = Instant::now(); - rows.run_once()?; - if let Some(ref mut stats) = statistics { - stats.io_time_elapsed_samples.push(start.elapsed()); - } - } - Ok(StepResult::Interrupt) => { - if let Some(ref mut stats) = statistics { - stats.execute_time_elapsed_samples.push(start.elapsed()); - } - break; - } - Ok(StepResult::Done) => { - if let Some(ref mut stats) = statistics { - stats.execute_time_elapsed_samples.push(start.elapsed()); - } - break; - } - Ok(StepResult::Busy) => { - if let Some(ref mut stats) = statistics { - stats.execute_time_elapsed_samples.push(start.elapsed()); - } - let _ = self.writeln("database is busy"); - break; - } - Err(err) => { - if let Some(ref mut stats) = statistics { - stats.execute_time_elapsed_samples.push(start.elapsed()); - } - let report = - miette::Error::from(err).with_source_code(sql.to_owned()); - let _ = self.write_fmt(format_args!("{report:?}")); - break; - } - } + table.add_row(row); + }); } if !table.is_empty() { - let _ = self.write_fmt(format_args!("{table}")); + writeln!(self, "{table}")?; } } OutputMode::Line => { let mut first_row_printed = false; + + let max_width = (0..rows.num_columns()) + .map(|i| rows.get_column_name(i).len()) + .max() + .unwrap_or(0); + + let formatted_columns: Vec = (0..rows.num_columns()) + .map(|i| format!("{:>width$}", rows.get_column_name(i), width = max_width)) + .collect(); + loop { - if self.interrupt_count.load(Ordering::Acquire) > 0 { - println!("Query interrupted."); - return Ok(()); - } + row_step_result_query!(self, sql, rows, statistics, { + let record = rows.row().unwrap(); - let start = Instant::now(); + if !first_row_printed { + first_row_printed = true; + } else { + self.writeln("")?; + } - let max_width = (0..rows.num_columns()) - .map(|i| rows.get_column_name(i).len()) - .max() - .unwrap_or(0); - - let formatted_columns: Vec = (0..rows.num_columns()) - .map(|i| { - format!("{:>width$}", rows.get_column_name(i), width = max_width) - }) - .collect(); - - match rows.step() { - Ok(StepResult::Row) => { - if let Some(ref mut stats) = statistics { - stats.execute_time_elapsed_samples.push(start.elapsed()); - } - let record = rows.row().unwrap(); - - if !first_row_printed { - first_row_printed = true; + for (i, value) in record.get_values().enumerate() { + self.write(&formatted_columns[i])?; + self.write(b" = ")?; + if matches!(value, Value::Null) { + self.write_null()?; } else { - self.writeln("")?; - } - - for (i, value) in record.get_values().enumerate() { - self.write(&formatted_columns[i])?; - self.write(b" = ")?; - if matches!(value, Value::Null) { - let bytes = self.opts.null_value.clone(); - self.write(bytes.as_bytes())?; - } else { - self.write(format!("{value}").as_bytes())?; - } - self.writeln("")?; + write!(self, "{value}")?; } + self.writeln("")?; } - Ok(StepResult::IO) => { - let start = Instant::now(); - rows.run_once()?; - if let Some(ref mut stats) = statistics { - stats.io_time_elapsed_samples.push(start.elapsed()); - } - } - Ok(StepResult::Interrupt) => { - if let Some(ref mut stats) = statistics { - stats.execute_time_elapsed_samples.push(start.elapsed()); - } - break; - } - Ok(StepResult::Done) => { - if let Some(ref mut stats) = statistics { - stats.execute_time_elapsed_samples.push(start.elapsed()); - } - break; - } - Ok(StepResult::Busy) => { - if let Some(ref mut stats) = statistics { - stats.execute_time_elapsed_samples.push(start.elapsed()); - } - let _ = self.writeln("database is busy"); - break; - } - Err(err) => { - if let Some(ref mut stats) = statistics { - stats.execute_time_elapsed_samples.push(start.elapsed()); - } - let report = - miette::Error::from(err).with_source_code(sql.to_owned()); - let _ = self.write_fmt(format_args!("{report:?}")); - break; - } - } + }); } } }, Ok(None) => {} Err(err) => { let report = miette::Error::from(err).with_source_code(sql.to_owned()); - let _ = self.write_fmt(format_args!("{report:?}")); + let _ = self.writeln_fmt(format_args!("{report:?}")); anyhow::bail!("We have to throw here, even if we printed error"); } } @@ -1034,13 +958,13 @@ impl Limbo { schema_str.to_string() } }; - let _ = self.write_fmt(format_args!("{modified_schema};")); + let _ = self.writeln_fmt(format_args!("{modified_schema};")); // For views, add the column comment like SQLite does if obj_type.as_str() == "view" { let columns = self .get_view_columns(obj_name.as_str()) .unwrap_or_else(|_| "x".to_string()); - let _ = self.write_fmt(format_args!("/* {}({}) */", obj_name.as_str(), columns)); + let _ = self.writeln_fmt(format_args!("/* {}({}) */", obj_name.as_str(), columns)); } true } else { @@ -1180,7 +1104,7 @@ impl Limbo { format!("{target_db}.{table_name}") }; let _ = self - .write_fmt(format_args!("-- Error: Table '{table_display}' not found.")); + .writeln_fmt(format_args!("-- Error: Table '{table_display}' not found.")); } } None => { @@ -1257,7 +1181,7 @@ impl Limbo { if !tables.is_empty() { let _ = self.writeln(tables.trim_end().as_bytes()); } else if let Some(pattern) = pattern { - let _ = self.write_fmt(format_args!( + let _ = self.writeln_fmt(format_args!( "Error: Tables with pattern '{pattern}' not found." )); } else { diff --git a/core/json/vtab.rs b/core/json/vtab.rs index 8957b951c..00e88b615 100644 --- a/core/json/vtab.rs +++ b/core/json/vtab.rs @@ -1,11 +1,11 @@ use std::{cell::RefCell, result::Result, sync::Arc}; -use turso_ext::{ConstraintUsage, ResultCode}; +use turso_ext::{ConstraintOp, ConstraintUsage, ResultCode}; use crate::{ json::{ - convert_dbtype_to_jsonb, - jsonb::{ArrayIteratorState, Jsonb, ObjectIteratorState}, + convert_dbtype_to_jsonb, json_path_from_db_value, + jsonb::{ArrayIteratorState, Jsonb, ObjectIteratorState, SearchOperation}, vtab::columns::Columns, Conv, }, @@ -46,8 +46,6 @@ impl InternalVirtualTable for JsonEachVirtualTable { constraints: &[turso_ext::ConstraintInfo], _order_by: &[turso_ext::OrderByInfo], ) -> Result { - use turso_ext::ConstraintOp; - let mut usages = vec![ ConstraintUsage { argv_index: None, @@ -55,25 +53,51 @@ impl InternalVirtualTable for JsonEachVirtualTable { }; constraints.len() ]; - let mut have_json = false; + let mut json_idx: Option = None; + let mut path_idx: Option = None; for (i, c) in constraints.iter().enumerate() { - if c.usable && c.op == ConstraintOp::Eq && c.column_index as usize == COL_JSON { - usages[i] = ConstraintUsage { - argv_index: Some(1), - omit: true, - }; - have_json = true; - break; + if !c.usable || c.op != ConstraintOp::Eq { + continue; + } + match c.column_index as usize { + COL_JSON => json_idx = Some(i), + COL_ROOT => path_idx = Some(i), + _ => {} } } + let argc = match (json_idx, path_idx) { + (Some(_), Some(_)) => 2, + (Some(_), None) => 1, + _ => 0, + }; + + if argc >= 1 { + usages[json_idx.unwrap()] = ConstraintUsage { + argv_index: Some(1), + omit: true, + }; + } + if argc == 2 { + usages[path_idx.unwrap()] = ConstraintUsage { + argv_index: Some(2), + omit: true, + }; + } + + let (cost, rows) = match argc { + 1 => (1., 25), + 2 => (1., 25), + _ => (f64::MAX, 25), + }; + Ok(turso_ext::IndexInfo { - idx_num: i32::from(have_json), + idx_num: -1, idx_str: None, order_by_consumed: false, - estimated_cost: if have_json { 10.0 } else { 1_000_000.0 }, - estimated_rows: if have_json { 100 } else { u32::MAX }, + estimated_cost: cost, + estimated_rows: rows, constraint_usages: usages, }) } @@ -112,6 +136,7 @@ pub struct JsonEachCursor { rowid: i64, no_more_rows: bool, json: Jsonb, + root_path: Option, iterator_state: IteratorState, columns: Columns, } @@ -122,6 +147,7 @@ impl Default for JsonEachCursor { rowid: 0, no_more_rows: false, json: Jsonb::new(0, None), + root_path: None, iterator_state: IteratorState::None, columns: Columns::default(), } @@ -138,25 +164,31 @@ impl InternalVirtualTableCursor for JsonEachCursor { if args.is_empty() { return Ok(false); } - if args.len() == 2 { - return Err(LimboError::InvalidArgument( - "2-arg json_each is not supported yet".to_owned(), - )); - } if args.len() != 1 && args.len() != 2 { return Err(LimboError::InvalidArgument( "json_each accepts 1 or 2 arguments".to_owned(), )); } - let db_value = &args[0]; + let mut jsonb = convert_dbtype_to_jsonb(&args[0], Conv::Strict)?; + if args.len() == 1 { + self.json = jsonb; + } else if args.len() == 2 { + let Value::Text(root_path) = &args[1] else { + return Err(LimboError::InvalidArgument( + "root path should be text".to_owned(), + )); + }; + self.root_path = Some(root_path.as_str().to_owned()); + self.json = if let Some(json) = navigate_to_path(&mut jsonb, &args[1])? { + json + } else { + return Ok(false); + }; + } + let json_element_type = self.json.element_type()?; - let jsonb = convert_dbtype_to_jsonb(db_value, Conv::Strict)?; - - let element_type = jsonb.element_type()?; - self.json = jsonb; - - match element_type { + match json_element_type { jsonb::ElementType::ARRAY => { let iter = self.json.array_iterator()?; self.iterator_state = IteratorState::Array(iter); @@ -181,7 +213,7 @@ impl InternalVirtualTableCursor for JsonEachCursor { jsonb::ElementType::RESERVED1 | jsonb::ElementType::RESERVED2 | jsonb::ElementType::RESERVED3 => { - unreachable!("element type not supported: {element_type:?}"); + unreachable!("element type not supported: {json_element_type:?}"); } }; @@ -201,7 +233,11 @@ impl InternalVirtualTableCursor for JsonEachCursor { return Ok(false); }; self.iterator_state = IteratorState::Array(new_state); - self.columns = Columns::new(columns::Key::Integer(idx as i64), jsonb); + self.columns = Columns::new( + columns::Key::Integer(idx as i64), + jsonb, + self.root_path.clone(), + ); } IteratorState::Object(state) => { let Some(((_idx, key, value), new_state)): Option<( @@ -214,11 +250,12 @@ impl InternalVirtualTableCursor for JsonEachCursor { self.iterator_state = IteratorState::Object(new_state); let key = key.to_string(); - self.columns = Columns::new(columns::Key::String(key), value); + self.columns = + Columns::new(columns::Key::String(key), value, self.root_path.clone()); } IteratorState::Primitive => { let json = std::mem::replace(&mut self.json, Jsonb::new(0, None)); - self.columns = Columns::new_from_primitive(json); + self.columns = Columns::new_from_primitive(json, self.root_path.clone()); self.no_more_rows = true; } IteratorState::None => unreachable!(), @@ -247,6 +284,20 @@ impl InternalVirtualTableCursor for JsonEachCursor { } } +fn navigate_to_path(jsonb: &mut Jsonb, path: &Value) -> Result, LimboError> { + let json_path = json_path_from_db_value(path, true)?.ok_or_else(|| { + LimboError::InvalidArgument(format!("path '{path}' is not a valid json path")) + })?; + let mut search_operation = SearchOperation::new(jsonb.len() / 2); + if jsonb + .operate_on_path(&json_path, &mut search_operation) + .is_err() + { + return Ok(None); + } + Ok(Some(search_operation.result())) +} + mod columns { use crate::{ json::{ @@ -262,16 +313,17 @@ mod columns { pub(super) enum Key { Integer(i64), String(String), + None, } impl Key { fn empty() -> Self { - Self::Integer(0) + Self::None } - fn fullkey_representation(&self) -> Value { + fn fullkey_representation(&self, root_path: &str) -> Value { match self { - Key::Integer(ref i) => Value::Text(Text::new(&format!("$[{i}]"))), + Key::Integer(ref i) => Value::Text(Text::new(&format!("{root_path}[{i}]"))), Key::String(ref text) => { let mut needs_quoting: bool = false; @@ -283,10 +335,11 @@ mod columns { if needs_quoting { text = format!("\"{text}\""); } - let s = format!("$.{text}"); + let s = format!("{root_path}.{text}"); Value::Text(Text::new(&s)) } + Key::None => Value::Text(Text::new(root_path)), } } @@ -296,6 +349,7 @@ mod columns { Key::String(ref s) => Value::Text(Text::new( &s[1..s.len() - 1].to_owned().replace("\\\"", "\""), )), + Key::None => Value::Null, } } } @@ -303,7 +357,7 @@ mod columns { pub(super) struct Columns { key: Key, value: Jsonb, - is_primitive: bool, + root_path: String, } impl Default for Columns { @@ -311,25 +365,25 @@ mod columns { Self { key: Key::empty(), value: Jsonb::new(0, None), - is_primitive: false, + root_path: String::new(), } } } impl Columns { - pub(super) fn new(key: Key, value: Jsonb) -> Self { + pub(super) fn new(key: Key, value: Jsonb, root_path: Option) -> Self { Self { key, value, - is_primitive: false, + root_path: root_path.unwrap_or_else(|| "$".to_owned()), } } - pub(super) fn new_from_primitive(value: Jsonb) -> Self { + pub(super) fn new_from_primitive(value: Jsonb, root_path: Option) -> Self { Self { key: Key::empty(), value, - is_primitive: true, + root_path: root_path.unwrap_or_else(|| "$".to_owned()), } } @@ -348,9 +402,6 @@ mod columns { } pub(super) fn key(&self) -> Value { - if self.is_primitive { - return Value::Null; - } self.key.key_representation() } @@ -397,14 +448,11 @@ mod columns { } pub(super) fn fullkey(&self) -> Value { - if self.is_primitive { - return Value::Text(Text::new("$")); - } - self.key.fullkey_representation() + self.key.fullkey_representation(&self.root_path) } pub(super) fn path(&self) -> Value { - Value::Text(Text::new("$")) + Value::Text(Text::new(&self.root_path)) } pub(super) fn parent(&self) -> Value { diff --git a/core/lib.rs b/core/lib.rs index 2e30e51f9..544b81cbf 100644 --- a/core/lib.rs +++ b/core/lib.rs @@ -626,6 +626,38 @@ impl Database { Ok(pager) } + #[cfg(feature = "fs")] + pub fn io_for_path(path: &str) -> Result> { + use crate::util::MEMORY_PATH; + let io: Arc = match path.trim() { + MEMORY_PATH => Arc::new(MemoryIO::new()), + _ => Arc::new(PlatformIO::new()?), + }; + Ok(io) + } + + #[cfg(feature = "fs")] + pub fn io_for_vfs + std::fmt::Display>(vfs: S) -> Result> { + let vfsmods = ext::add_builtin_vfs_extensions(None)?; + let io: Arc = match vfsmods + .iter() + .find(|v| v.0 == vfs.as_ref()) + .map(|v| v.1.clone()) + { + Some(vfs) => vfs, + None => match vfs.as_ref() { + "memory" => Arc::new(MemoryIO::new()), + "syscall" => Arc::new(SyscallIO::new()?), + #[cfg(all(target_os = "linux", feature = "io_uring"))] + "io_uring" => Arc::new(UringIO::new()?), + other => { + return Err(LimboError::InvalidArgument(format!("no such VFS: {other}"))); + } + }, + }; + Ok(io) + } + /// Open a new database file with optionally specifying a VFS without an existing database /// connection and symbol table to register extensions. #[cfg(feature = "fs")] @@ -639,40 +671,13 @@ impl Database { where S: AsRef + std::fmt::Display, { - use crate::util::MEMORY_PATH; - let vfsmods = ext::add_builtin_vfs_extensions(None)?; - match vfs { - Some(vfs) => { - let io: Arc = match vfsmods - .iter() - .find(|v| v.0 == vfs.as_ref()) - .map(|v| v.1.clone()) - { - Some(vfs) => vfs, - None => match vfs.as_ref() { - "memory" => Arc::new(MemoryIO::new()), - "syscall" => Arc::new(SyscallIO::new()?), - #[cfg(all(target_os = "linux", feature = "io_uring"))] - "io_uring" => Arc::new(UringIO::new()?), - other => { - return Err(LimboError::InvalidArgument(format!( - "no such VFS: {other}" - ))); - } - }, - }; - let db = Self::open_file_with_flags(io.clone(), path, flags, opts)?; - Ok((io, db)) - } - None => { - let io: Arc = match path.trim() { - MEMORY_PATH => Arc::new(MemoryIO::new()), - _ => Arc::new(PlatformIO::new()?), - }; - let db = Self::open_file_with_flags(io.clone(), path, flags, opts)?; - Ok((io, db)) - } - } + let io = vfs + .map(|vfs| Self::io_for_vfs(vfs)) + .or_else(|| Some(Self::io_for_path(path))) + .transpose()? + .unwrap(); + let db = Self::open_file_with_flags(io.clone(), path, flags, opts)?; + Ok((io, db)) } #[inline] @@ -1304,12 +1309,17 @@ impl Connection { } #[cfg(feature = "fs")] - fn from_uri_attached(uri: &str, db_opts: DatabaseOpts) -> Result> { + fn from_uri_attached( + uri: &str, + db_opts: DatabaseOpts, + io: Arc, + ) -> Result> { let mut opts = OpenOptions::parse(uri)?; // FIXME: for now, only support read only attach opts.mode = OpenMode::ReadOnly; let flags = opts.get_flags()?; - let (_io, db) = Database::open_new(&opts.path, opts.vfs.as_ref(), flags, db_opts)?; + let io = opts.vfs.map(Database::io_for_vfs).unwrap_or(Ok(io))?; + let db = Database::open_file_with_flags(io.clone(), &opts.path, flags, db_opts)?; if let Some(modeof) = opts.modeof { let perms = std::fs::metadata(modeof)?; std::fs::set_permissions(&opts.path, perms.permissions())?; @@ -1852,7 +1862,7 @@ impl Connection { .with_indexes(use_indexes) .with_views(use_views) .with_strict(use_strict); - let db = Self::from_uri_attached(path, db_opts)?; + let db = Self::from_uri_attached(path, db_opts, self._db.io.clone())?; let pager = Rc::new(db.init_pager(None)?); self.attached_databases diff --git a/core/storage/page_cache.rs b/core/storage/page_cache.rs index c125f44c8..c5a70d614 100644 --- a/core/storage/page_cache.rs +++ b/core/storage/page_cache.rs @@ -528,20 +528,36 @@ impl PageCache { } pub fn clear(&mut self) -> Result<(), CacheError> { - for e in self.entries.iter() { + if self.map.len() == 0 { + // Fast path: nothing to do. + self.clock_hand = NULL; + return Ok(()); + } + + for node in self.map.iter() { + let e = &self.entries[node.slot_index]; if let Some(ref p) = e.page { if p.is_dirty() { return Err(CacheError::Dirty { pgno: p.get().id }); } + } + } + let mut used_slots = Vec::with_capacity(self.map.len()); + for node in self.map.iter() { + used_slots.push(node.slot_index); + } + // don't touch already-free slots at all. + for &i in &used_slots { + if let Some(p) = self.entries[i].page.take() { p.clear_loaded(); let _ = p.get().contents.take(); } + self.entries[i].clear_ref(); + self.entries[i].reset_links(); } - self.entries.fill(PageCacheEntry::empty()); - self.map.clear(); self.clock_hand = NULL; - self.freelist.clear(); - for i in (0..self.capacity).rev() { + self.map = PageHashMap::new(self.capacity); + for &i in used_slots.iter().rev() { self.freelist.push(i); } Ok(()) @@ -631,16 +647,6 @@ impl PageCache { self.capacity } - pub fn unset_dirty_all_pages(&mut self) { - let entries = &self.entries; - for entry in entries.iter() { - if entry.page.is_none() { - continue; - } - entry.page.as_ref().unwrap().clear_dirty(); - } - } - #[cfg(test)] fn verify_cache_integrity(&self) { let map = &self.map; diff --git a/core/storage/pager.rs b/core/storage/pager.rs index 31eb980cd..f2fb9d160 100644 --- a/core/storage/pager.rs +++ b/core/storage/pager.rs @@ -1563,12 +1563,15 @@ impl Pager { /// of a rollback or in case we want to invalidate page cache after starting a read transaction /// right after new writes happened which would invalidate current page cache. pub fn clear_page_cache(&self) { - self.dirty_pages.borrow_mut().clear(); - self.page_cache.write().unset_dirty_all_pages(); - self.page_cache - .write() - .clear() - .expect("Failed to clear page cache"); + let dirty_pages = self.dirty_pages.borrow(); + let mut cache = self.page_cache.write(); + for page_id in dirty_pages.iter() { + let page_key = PageCacheKey::new(*page_id); + if let Some(page) = cache.get(&page_key).unwrap_or(None) { + page.clear_dirty(); + } + } + cache.clear().expect("Failed to clear page cache"); } /// Checkpoint in Truncate mode and delete the WAL file. This method is _only_ to be called @@ -2118,6 +2121,7 @@ impl Pager { is_write: bool, ) -> Result<(), LimboError> { tracing::debug!(schema_did_change); + self.clear_page_cache(); if is_write { self.dirty_pages.borrow_mut().clear(); } else { @@ -2126,12 +2130,7 @@ impl Pager { "dirty pages should be empty for read txn" ); } - let mut cache = self.page_cache.write(); - self.reset_internal_states(); - - cache.unset_dirty_all_pages(); - cache.clear().expect("failed to clear page cache"); if schema_did_change { connection.schema.replace(connection._db.clone_schema()?); } diff --git a/core/storage/sqlite3_ondisk.rs b/core/storage/sqlite3_ondisk.rs index 696d10d05..0d7fbcee9 100644 --- a/core/storage/sqlite3_ondisk.rs +++ b/core/storage/sqlite3_ondisk.rs @@ -1622,11 +1622,14 @@ pub fn write_varint_to_vec(value: u64, payload: &mut Vec) { payload.extend_from_slice(&varint[0..n]); } -/// We need to read the WAL file on open to reconstruct the WAL frame cache. -pub fn read_entire_wal_dumb(file: &Arc) -> Result>> { +/// Stream through frames in chunks, building frame_cache incrementally +/// Track last valid commit frame for consistency +pub fn build_shared_wal( + file: &Arc, + io: &Arc, +) -> Result>> { let size = file.size()?; - #[allow(clippy::arc_with_non_send_sync)] - let buf_for_pread = Arc::new(Buffer::new_temporary(size as usize)); + let header = Arc::new(SpinLock::new(WalHeader::default())); let read_locks = std::array::from_fn(|_| TursoRwLock::new()); for (i, l) in read_locks.iter().enumerate() { @@ -1634,8 +1637,8 @@ pub fn read_entire_wal_dumb(file: &Arc) -> Result) -> Result = Box::new(move |res: Result<(Arc, i32), _>| { + + if size < WAL_HEADER_SIZE as u64 { + wal_file_shared.write().loaded.store(true, Ordering::SeqCst); + return Ok(wal_file_shared); + } + + let reader = Arc::new(StreamingWalReader::new( + file.clone(), + wal_file_shared.clone(), + header.clone(), + size, + )); + + let h = reader.clone().read_header()?; + io.wait_for_completion(h)?; + + loop { + if reader.done.load(Ordering::Acquire) { + break; + } + let offset = reader.off_atomic.load(Ordering::Acquire); + if offset >= size { + reader.finalize_loading(); + break; + } + + let (_read_size, c) = reader.clone().submit_one_chunk(offset)?; + io.wait_for_completion(c)?; + + let new_off = reader.off_atomic.load(Ordering::Acquire); + if new_off <= offset { + reader.finalize_loading(); + break; + } + } + + Ok(wal_file_shared) +} + +pub(super) struct StreamingWalReader { + file: Arc, + wal_shared: Arc>, + header: Arc>, + file_size: u64, + state: RwLock, + off_atomic: AtomicU64, + page_atomic: AtomicU64, + pub(super) done: AtomicBool, +} + +/// Mutable state for streaming reader +struct StreamingState { + frame_idx: u64, + cumulative_checksum: (u32, u32), + last_valid_frame: u64, + pending_frames: HashMap>, + page_size: usize, + use_native_endian: bool, + header_valid: bool, +} + +impl StreamingWalReader { + fn new( + file: Arc, + wal_shared: Arc>, + header: Arc>, + file_size: u64, + ) -> Self { + Self { + file, + wal_shared, + header, + file_size, + off_atomic: AtomicU64::new(0), + page_atomic: AtomicU64::new(0), + done: AtomicBool::new(false), + state: RwLock::new(StreamingState { + frame_idx: 1, + cumulative_checksum: (0, 0), + last_valid_frame: 0, + pending_frames: HashMap::new(), + page_size: 0, + use_native_endian: false, + header_valid: false, + }), + } + } + + fn read_header(self: Arc) -> crate::Result { + let header_buf = Arc::new(Buffer::new_temporary(WAL_HEADER_SIZE)); + let reader = self.clone(); + let completion: Box = Box::new(move |res| { + let _reader = reader.clone(); + _reader.handle_header_read(res); + }); + let c = Completion::new_read(header_buf, completion); + self.file.pread(0, c) + } + + fn submit_one_chunk(self: Arc, offset: u64) -> crate::Result<(usize, Completion)> { + let page_size = self.page_atomic.load(Ordering::Acquire) as usize; + if page_size == 0 { + return Err(crate::LimboError::InternalError( + "page size not initialized".into(), + )); + } + let frame_size = WAL_FRAME_HEADER_SIZE + page_size; + if frame_size == 0 { + return Err(crate::LimboError::InternalError( + "invalid frame size".into(), + )); + } + const BASE: usize = 16 * 1024 * 1024; + let aligned = (BASE / frame_size) * frame_size; + let read_size = aligned + .max(frame_size) + .min((self.file_size - offset) as usize); + if read_size == 0 { + // end-of-file; let caller finalize + return Ok((0, Completion::new_dummy())); + } + + let buf = Arc::new(Buffer::new_temporary(read_size)); + let me = self.clone(); + let completion: Box = Box::new(move |res| { + tracing::debug!("WAL chunk read complete"); + let reader = me.clone(); + reader.handle_chunk_read(res); + }); + let c = Completion::new_read(buf, completion); + let guard = self.file.pread(offset, c)?; + Ok((read_size, guard)) + } + + fn handle_header_read(self: Arc, res: Result<(Arc, i32), CompletionError>) { let Ok((buf, bytes_read)) = res else { + self.finalize_loading(); return; }; - let buf_slice = buf.as_slice(); - turso_assert!( - bytes_read == buf_slice.len() as i32, - "read({bytes_read}) != expected({})", - buf_slice.len() - ); - let mut header_locked = header.lock(); - // Read header - header_locked.magic = - u32::from_be_bytes([buf_slice[0], buf_slice[1], buf_slice[2], buf_slice[3]]); - header_locked.file_format = - u32::from_be_bytes([buf_slice[4], buf_slice[5], buf_slice[6], buf_slice[7]]); - header_locked.page_size = - u32::from_be_bytes([buf_slice[8], buf_slice[9], buf_slice[10], buf_slice[11]]); - header_locked.checkpoint_seq = - u32::from_be_bytes([buf_slice[12], buf_slice[13], buf_slice[14], buf_slice[15]]); - header_locked.salt_1 = - u32::from_be_bytes([buf_slice[16], buf_slice[17], buf_slice[18], buf_slice[19]]); - header_locked.salt_2 = - u32::from_be_bytes([buf_slice[20], buf_slice[21], buf_slice[22], buf_slice[23]]); - header_locked.checksum_1 = - u32::from_be_bytes([buf_slice[24], buf_slice[25], buf_slice[26], buf_slice[27]]); - header_locked.checksum_2 = - u32::from_be_bytes([buf_slice[28], buf_slice[29], buf_slice[30], buf_slice[31]]); - tracing::debug!("read_entire_wal_dumb(header={:?})", *header_locked); - - // Read frames into frame_cache and pages_in_frames - if buf_slice.len() < WAL_HEADER_SIZE { - panic!("WAL file too small for header"); + if bytes_read != WAL_HEADER_SIZE as i32 { + self.finalize_loading(); + return; } - let use_native_endian_checksum = - cfg!(target_endian = "big") == ((header_locked.magic & 1) != 0); + let (page_sz, c1, c2, use_native, ok) = { + let mut h = self.header.lock(); + let s = buf.as_slice(); + h.magic = u32::from_be_bytes(s[0..4].try_into().unwrap()); + h.file_format = u32::from_be_bytes(s[4..8].try_into().unwrap()); + h.page_size = u32::from_be_bytes(s[8..12].try_into().unwrap()); + h.checkpoint_seq = u32::from_be_bytes(s[12..16].try_into().unwrap()); + h.salt_1 = u32::from_be_bytes(s[16..20].try_into().unwrap()); + h.salt_2 = u32::from_be_bytes(s[20..24].try_into().unwrap()); + h.checksum_1 = u32::from_be_bytes(s[24..28].try_into().unwrap()); + h.checksum_2 = u32::from_be_bytes(s[28..32].try_into().unwrap()); + tracing::debug!("WAL header: {:?}", *h); - let calculated_header_checksum = checksum_wal( - &buf_slice[0..24], - &header_locked, - (0, 0), - use_native_endian_checksum, - ); - - let checksum_header_failed = if calculated_header_checksum - != (header_locked.checksum_1, header_locked.checksum_2) + let use_native = cfg!(target_endian = "big") == ((h.magic & 1) != 0); + let calc = checksum_wal(&s[0..24], &h, (0, 0), use_native); + ( + h.page_size, + h.checksum_1, + h.checksum_2, + use_native, + calc == (h.checksum_1, h.checksum_2), + ) + }; + if PageSize::new(page_sz).is_none() || !ok { + self.finalize_loading(); + return; + } { - tracing::error!( - "WAL header checksum mismatch. Expected ({}, {}), Got ({}, {}). Ignoring frames starting from frame {}", - header_locked.checksum_1, - header_locked.checksum_2, - calculated_header_checksum.0, - calculated_header_checksum.1, - 0 + let mut st = self.state.write(); + st.page_size = page_sz as usize; + st.use_native_endian = use_native; + st.cumulative_checksum = (c1, c2); + st.header_valid = true; + } + self.off_atomic + .store(WAL_HEADER_SIZE as u64, Ordering::Release); + self.page_atomic.store(page_sz as u64, Ordering::Release); + } - ); - true - } else { - false + fn handle_chunk_read(self: Arc, res: Result<(Arc, i32), CompletionError>) { + let Ok((buf, bytes_read)) = res else { + self.finalize_loading(); + return; + }; + let buf_slice = &buf.as_slice()[..bytes_read as usize]; + // Snapshot salts/endianness once to avoid per-frame header locks + let (header_copy, use_native) = { + let st = self.state.read(); + let h = self.header.lock(); + (*h, st.use_native_endian) }; - let mut cumulative_checksum = (header_locked.checksum_1, header_locked.checksum_2); - let page_size_u32 = header_locked.page_size; - - if PageSize::new(page_size_u32).is_none() { - panic!("Invalid page size in WAL header: {page_size_u32}"); + let consumed = self.process_frames(buf_slice, &header_copy, use_native); + self.off_atomic.fetch_add(consumed as u64, Ordering::AcqRel); + // If we didn’t consume the full chunk, we hit a stop condition + if consumed < buf_slice.len() || self.off_atomic.load(Ordering::Acquire) >= self.file_size { + self.finalize_loading(); } - let page_size = page_size_u32 as usize; + } - let mut current_offset = WAL_HEADER_SIZE; - let mut frame_idx = 1_u64; + // Processes frames from a buffer, returns bytes processed + fn process_frames(&self, buf: &[u8], header: &WalHeader, use_native: bool) -> usize { + let mut st = self.state.write(); + let page_size = st.page_size; + let frame_size = WAL_FRAME_HEADER_SIZE + page_size; + let mut pos = 0; - let mut wfs_data = wal_file_shared_for_completion.write(); + while pos + frame_size <= buf.len() { + let fh = &buf[pos..pos + WAL_FRAME_HEADER_SIZE]; + let page = &buf[pos + WAL_FRAME_HEADER_SIZE..pos + frame_size]; - if !checksum_header_failed { - while current_offset + WAL_FRAME_HEADER_SIZE + page_size <= buf_slice.len() { - let frame_header_slice = - &buf_slice[current_offset..current_offset + WAL_FRAME_HEADER_SIZE]; - let page_data_slice = &buf_slice[current_offset + WAL_FRAME_HEADER_SIZE - ..current_offset + WAL_FRAME_HEADER_SIZE + page_size]; + let page_number = u32::from_be_bytes(fh[0..4].try_into().unwrap()); + let db_size = u32::from_be_bytes(fh[4..8].try_into().unwrap()); + let s1 = u32::from_be_bytes(fh[8..12].try_into().unwrap()); + let s2 = u32::from_be_bytes(fh[12..16].try_into().unwrap()); + let c1 = u32::from_be_bytes(fh[16..20].try_into().unwrap()); + let c2 = u32::from_be_bytes(fh[20..24].try_into().unwrap()); - let frame_h_page_number = - u32::from_be_bytes(frame_header_slice[0..4].try_into().unwrap()); - let frame_h_db_size = - u32::from_be_bytes(frame_header_slice[4..8].try_into().unwrap()); - let frame_h_salt_1 = - u32::from_be_bytes(frame_header_slice[8..12].try_into().unwrap()); - let frame_h_salt_2 = - u32::from_be_bytes(frame_header_slice[12..16].try_into().unwrap()); - let frame_h_checksum_1 = - u32::from_be_bytes(frame_header_slice[16..20].try_into().unwrap()); - let frame_h_checksum_2 = - u32::from_be_bytes(frame_header_slice[20..24].try_into().unwrap()); + if page_number == 0 { + break; + } + if s1 != header.salt_1 || s2 != header.salt_2 { + break; + } - if frame_h_page_number == 0 { - tracing::trace!( - "WAL frame with page number 0. Ignoring frames starting from frame {}", - frame_idx - ); - break; + let seed = checksum_wal(&fh[0..8], header, st.cumulative_checksum, use_native); + let calc = checksum_wal(page, header, seed, use_native); + if calc != (c1, c2) { + break; + } + + st.cumulative_checksum = calc; + let frame_idx = st.frame_idx; + st.pending_frames + .entry(page_number as u64) + .or_default() + .push(frame_idx); + + if db_size > 0 { + st.last_valid_frame = st.frame_idx; + self.flush_pending_frames(&mut st); + } + st.frame_idx += 1; + pos += frame_size; + } + pos + } + + fn flush_pending_frames(&self, state: &mut StreamingState) { + if state.pending_frames.is_empty() { + return; + } + let wfs = self.wal_shared.read(); + { + let mut frame_cache = wfs.frame_cache.lock(); + for (page, mut frames) in state.pending_frames.drain() { + // Only include frames up to last valid commit + frames.retain(|&f| f <= state.last_valid_frame); + if !frames.is_empty() { + frame_cache.entry(page).or_default().extend(frames); } - // It contains more frames with mismatched SALT values, which means they're leftovers from previous checkpoints - if frame_h_salt_1 != header_locked.salt_1 || frame_h_salt_2 != header_locked.salt_2 - { - tracing::trace!( - "WAL frame salt mismatch: expected ({}, {}), got ({}, {}). Ignoring frames starting from frame {}", - header_locked.salt_1, - header_locked.salt_2, - frame_h_salt_1, - frame_h_salt_2, - frame_idx - ); - break; - } - - let checksum_after_fh_meta = checksum_wal( - &frame_header_slice[0..8], - &header_locked, - cumulative_checksum, - use_native_endian_checksum, - ); - let calculated_frame_checksum = checksum_wal( - page_data_slice, - &header_locked, - checksum_after_fh_meta, - use_native_endian_checksum, - ); - tracing::debug!( - "read_entire_wal_dumb(frame_h_checksum=({}, {}), calculated_frame_checksum=({}, {}))", - frame_h_checksum_1, - frame_h_checksum_2, - calculated_frame_checksum.0, - calculated_frame_checksum.1 - ); - - if calculated_frame_checksum != (frame_h_checksum_1, frame_h_checksum_2) { - tracing::error!( - "WAL frame checksum mismatch. Expected ({}, {}), Got ({}, {}). Ignoring frames starting from frame {}", - frame_h_checksum_1, - frame_h_checksum_2, - calculated_frame_checksum.0, - calculated_frame_checksum.1, - frame_idx - ); - break; - } - - cumulative_checksum = calculated_frame_checksum; - - wfs_data - .frame_cache - .lock() - .entry(frame_h_page_number as u64) - .or_default() - .push(frame_idx); - - let is_commit_record = frame_h_db_size > 0; - if is_commit_record { - wfs_data.max_frame.store(frame_idx, Ordering::SeqCst); - wfs_data.last_checksum = cumulative_checksum; - } - - frame_idx += 1; - current_offset += WAL_FRAME_HEADER_SIZE + page_size; } } + wfs.max_frame + .store(state.last_valid_frame, Ordering::Release); + } - let max_frame = wfs_data.max_frame.load(Ordering::SeqCst); + /// Finalizes the loading process + fn finalize_loading(&self) { + let mut wfs = self.wal_shared.write(); + let st = self.state.read(); - // cleanup in-memory index from tail frames which was written after the last committed frame - let mut frame_cache = wfs_data.frame_cache.lock(); - for (page, frames) in frame_cache.iter_mut() { - // remove any frame IDs > max_frame - let original_len = frames.len(); - frames.retain(|&frame_id| frame_id <= max_frame); - if frames.len() < original_len { - tracing::debug!( - "removed {} frame(s) from page {} from the in-memory WAL index because they were written after the last committed frame {}", - original_len - frames.len(), - page, - max_frame - ); + let max_frame = st.last_valid_frame; + if max_frame > 0 { + let mut frame_cache = wfs.frame_cache.lock(); + for frames in frame_cache.values_mut() { + frames.retain(|&f| f <= max_frame); } + frame_cache.retain(|_, frames| !frames.is_empty()); } - // also remove any pages that now have no frames - frame_cache.retain(|_page, frames| !frames.is_empty()); - wfs_data.nbackfills.store(0, Ordering::SeqCst); - wfs_data.loaded.store(true, Ordering::SeqCst); - if size >= WAL_HEADER_SIZE as u64 { - wfs_data.initialized.store(true, Ordering::SeqCst); + wfs.max_frame.store(max_frame, Ordering::SeqCst); + wfs.last_checksum = st.cumulative_checksum; + if st.header_valid { + wfs.initialized.store(true, Ordering::SeqCst); } - }); - let c = Completion::new_read(buf_for_pread, complete); - let _c = file.pread(0, c)?; + wfs.nbackfills.store(0, Ordering::SeqCst); + wfs.loaded.store(true, Ordering::SeqCst); - Ok(wal_file_shared_ret) + self.done.store(true, Ordering::Release); + tracing::info!( + "WAL loading complete: {} frames processed, last commit at frame {}", + st.frame_idx - 1, + max_frame + ); + } } pub fn begin_read_wal_frame_raw( @@ -1859,7 +1963,6 @@ pub fn begin_read_wal_frame_raw( ) -> Result { tracing::trace!("begin_read_wal_frame_raw(offset={})", offset); let buf = Arc::new(buffer_pool.get_wal_frame()); - #[allow(clippy::arc_with_non_send_sync)] let c = Completion::new_read(buf, complete); let c = io.pread(offset, c)?; Ok(c) diff --git a/core/storage/wal.rs b/core/storage/wal.rs index f932964fb..d21267bbb 100644 --- a/core/storage/wal.rs +++ b/core/storage/wal.rs @@ -553,7 +553,6 @@ impl fmt::Debug for OngoingCheckpoint { } } -#[allow(dead_code)] pub struct WalFile { io: Arc, buffer_pool: Arc, @@ -660,7 +659,6 @@ impl fmt::Debug for WalFile { // TODO(pere): lock only important parts + pin WalFileShared /// WalFileShared is the part of a WAL that will be shared between threads. A wal has information /// that needs to be communicated between threads so this struct does the job. -#[allow(dead_code)] pub struct WalFileShared { pub enabled: AtomicBool, pub wal_header: Arc>, @@ -676,7 +674,6 @@ pub struct WalFileShared { pub frame_cache: Arc>>>, pub last_checksum: (u32, u32), // Check of last frame in WAL, this is a cumulative checksum over all frames in the WAL pub file: Option>, - /// Read locks advertise the maximum WAL frame a reader may access. /// Slot 0 is special, when it is held (shared) the reader bypasses the WAL and uses the main DB file. /// When checkpointing, we must acquire the exclusive read lock 0 to ensure that no readers read @@ -2238,21 +2235,17 @@ impl WalFileShared { path: &str, ) -> Result>> { let file = io.open_file(path, crate::io::OpenFlags::Create, false)?; - if file.size()? > 0 { - let wal_file_shared = sqlite3_ondisk::read_entire_wal_dumb(&file)?; - // TODO: Return a completion instead. - let mut max_loops = 100_000; - while !wal_file_shared.read().loaded.load(Ordering::Acquire) { - io.run_once()?; - max_loops -= 1; - if max_loops == 0 { - panic!("WAL file not loaded"); - } - } - Ok(wal_file_shared) - } else { - WalFileShared::new_noop() + if file.size()? == 0 { + return WalFileShared::new_noop(); } + let wal_file_shared = sqlite3_ondisk::build_shared_wal(&file, io)?; + turso_assert!( + wal_file_shared + .try_read() + .is_some_and(|wfs| wfs.loaded.load(Ordering::Acquire)), + "Unable to read WAL shared state" + ); + Ok(wal_file_shared) } pub fn is_initialized(&self) -> Result { diff --git a/core/translate/optimizer/mod.rs b/core/translate/optimizer/mod.rs index ba26a7935..e0b1c6b73 100644 --- a/core/translate/optimizer/mod.rs +++ b/core/translate/optimizer/mod.rs @@ -190,6 +190,34 @@ fn optimize_table_access( let maybe_order_target = compute_order_target(order_by, group_by.as_mut()); let constraints_per_table = constraints_from_where_clause(where_clause, table_references, available_indexes)?; + + // Currently the expressions we evaluate as constraints are binary expressions that will never be true for a NULL operand. + // If there are any constraints on the right hand side table of an outer join that are not part of the outer join condition, + // the outer join can be converted into an inner join. + // for example: + // - SELECT * FROM t1 LEFT JOIN t2 ON false WHERE t2.id = 5 + // there can never be a situation where null columns are emitted for t2 because t2.id = 5 will never be true in that case. + // hence: we can convert the outer join into an inner join. + for (i, t) in table_references + .joined_tables_mut() + .iter_mut() + .enumerate() + .filter(|(_, t)| { + t.join_info + .as_ref() + .is_some_and(|join_info| join_info.outer) + }) + { + if constraints_per_table[i] + .constraints + .iter() + .any(|c| where_clause[c.where_clause_pos.0].from_outer_join.is_none()) + { + t.join_info.as_mut().unwrap().outer = false; + continue; + } + } + let Some(best_join_order_result) = compute_best_join_order( table_references.joined_tables_mut(), maybe_order_target.as_ref(), diff --git a/core/vdbe/execute.rs b/core/vdbe/execute.rs index 0c6db224d..d5697b73c 100644 --- a/core/vdbe/execute.rs +++ b/core/vdbe/execute.rs @@ -1455,13 +1455,16 @@ pub fn op_column( index_cursor_id, table_cursor_id, } => { - let rowid = { + let Some(rowid) = ({ let index_cursor = state.get_cursor(index_cursor_id); let index_cursor = index_cursor.as_btree_mut(); return_if_io!(index_cursor.rowid()) + }) else { + state.registers[*dest] = Register::Value(Value::Null); + break 'outer; }; state.op_column_state = OpColumnState::Seek { - rowid: rowid.unwrap(), + rowid, table_cursor_id, }; } @@ -6991,16 +6994,34 @@ pub fn op_open_ephemeral( let conn = program.connection.clone(); let io = conn.pager.borrow().io.clone(); let rand_num = io.generate_random_number(); - let temp_dir = temp_dir(); - let rand_path = - std::path::Path::new(&temp_dir).join(format!("tursodb-ephemeral-{rand_num}")); - let Some(rand_path_str) = rand_path.to_str() else { - return Err(LimboError::InternalError( - "Failed to convert path to string".to_string(), - )); - }; - let file = io.open_file(rand_path_str, OpenFlags::Create, false)?; - let db_file = Arc::new(DatabaseFile::new(file)); + let db_file; + let db_file_io: Arc; + + // we support OPFS in WASM - but it require files to be pre-opened in the browser before use + // we can fix this if we will make open_file interface async + // but for now for simplicity we use MemoryIO for all intermediate calculations + #[cfg(target_family = "wasm")] + { + use crate::MemoryIO; + + db_file_io = Arc::new(MemoryIO::new()); + let file = db_file_io.open_file("temp-file", OpenFlags::Create, false)?; + db_file = Arc::new(DatabaseFile::new(file)); + } + #[cfg(not(target_family = "wasm"))] + { + let temp_dir = temp_dir(); + let rand_path = + std::path::Path::new(&temp_dir).join(format!("tursodb-ephemeral-{rand_num}")); + let Some(rand_path_str) = rand_path.to_str() else { + return Err(LimboError::InternalError( + "Failed to convert path to string".to_string(), + )); + }; + let file = io.open_file(rand_path_str, OpenFlags::Create, false)?; + db_file = Arc::new(DatabaseFile::new(file)); + db_file_io = io; + } let page_size = pager .io @@ -7013,7 +7034,7 @@ pub fn op_open_ephemeral( let pager = Rc::new(Pager::new( db_file, None, - io, + db_file_io, page_cache, buffer_pool.clone(), Arc::new(AtomicDbState::new(DbState::Uninitialized)), diff --git a/scripts/merge-pr.py b/scripts/merge-pr.py index 3aa48c683..21e774580 100755 --- a/scripts/merge-pr.py +++ b/scripts/merge-pr.py @@ -97,14 +97,46 @@ def wrap_text(text, width=72): return "\n".join(wrapped_lines) +def check_pr_status(pr_number): + """Check the status of all checks for a PR + + Returns a tuple of (has_failing, has_pending) indicating if there are + any failing or pending checks respectively. + """ + output, error, returncode = run_command(f"gh pr checks {pr_number} --json state,name,startedAt,completedAt") + if returncode != 0: + print(f"Warning: Unable to get PR check status: {error}") + return False, False + + checks_data = json.loads(output) + if not checks_data: + return False, False + + has_failing = any(check.get("state") == "FAILURE" for check in checks_data) + has_pending = any( + check.get("startedAt") and not check.get("completedAt") or check.get("state") == "IN_PROGRESS" + for check in checks_data + ) + return has_failing, has_pending + + def merge_remote(pr_number: int, commit_message: str, commit_title: str): - output, error, returncode = run_command(f"gh pr checks {pr_number} --json state") - if returncode == 0: - checks_data = json.loads(output) - if checks_data and any(check.get("state") == "FAILURE" for check in checks_data): - print("Warning: Some checks are failing") - if input("Do you want to proceed with the merge? (y/N): ").strip().lower() != "y": - exit(0) + has_failing, has_pending = check_pr_status(pr_number) + + prompt_needed = False + warning_msg = "" + + if has_failing: + prompt_needed = True + warning_msg = "Warning: Some checks are failing" + elif has_pending: + prompt_needed = True + warning_msg = "Warning: Some checks are still running" + + if prompt_needed: + print(warning_msg) + if input("Do you want to proceed with the merge? (y/N): ").strip().lower() != "y": + exit(0) # Create a temporary file for the commit message with tempfile.NamedTemporaryFile(mode="w", suffix=".txt", delete=False) as temp_file: @@ -131,6 +163,23 @@ def merge_remote(pr_number: int, commit_message: str, commit_title: str): def merge_local(pr_number: int, commit_message: str): + has_failing, has_pending = check_pr_status(pr_number) + + prompt_needed = False + warning_msg = "" + + if has_failing: + prompt_needed = True + warning_msg = "Warning: Some checks are failing" + elif has_pending: + prompt_needed = True + warning_msg = "Warning: Some checks are still running" + + if prompt_needed: + print(warning_msg) + if input("Do you want to proceed with the merge? (y/N): ").strip().lower() != "y": + exit(0) + current_branch, _, _ = run_command("git branch --show-current") print(f"Fetching PR #{pr_number}...") diff --git a/scripts/update-version.py b/scripts/update-version.py index b0c778aee..493350b02 100755 --- a/scripts/update-version.py +++ b/scripts/update-version.py @@ -17,13 +17,20 @@ from pathlib import Path # Define all npm package paths in one place NPM_PACKAGES = [ "bindings/javascript", - "bindings/javascript/npm/darwin-universal", - "bindings/javascript/npm/linux-x64-gnu", - "bindings/javascript/npm/win32-x64-msvc", - "bindings/javascript/npm/wasm32-wasip1-threads", + "bindings/javascript/packages/common", + "bindings/javascript/packages/native", + "bindings/javascript/packages/browser", "sync/javascript", ] +NPM_WORKSPACE_PACKAGES = [ + "@tursodatabase/database-common" +] + +NPM_WORKSPACES = [ + "bindings/javascript" +] + def parse_args(): parser = argparse.ArgumentParser(description="Update version in project files") @@ -79,6 +86,11 @@ def update_package_json(dir_path, new_version): # noqa: C901 # Update version regardless of current value package_data["version"] = new_version + if "dependencies" in package_data: + for dependency in package_data["dependencies"].keys(): + if dependency not in NPM_WORKSPACE_PACKAGES: + continue + package_data["dependencies"][dependency] = f"^{new_version}" # Write updated package.json with open(package_path, "w") as f: @@ -120,6 +132,25 @@ def update_package_json(dir_path, new_version): # noqa: C901 except Exception: return False +def run_npm_install(path): + """Run npm install to update package-lock.json""" + try: + # Run cargo update showing its output with verbose flag + print(f"Info: run npm install at path {path}") + subprocess.run(["npm", "install"], check=True, cwd=path) + return True + except Exception: + return False + +def run_yarn_install(path): + """Run yarn install to update yarn-lock.json""" + try: + # Run cargo update showing its output with verbose flag + print(f"Info: run yarn install at path {path}") + subprocess.run(["yarn", "install"], check=True, cwd=path) + return True + except Exception: + return False def update_all_packages(new_version): """Update all npm packages with the new version.""" @@ -127,6 +158,9 @@ def update_all_packages(new_version): for package_path in NPM_PACKAGES: result = update_package_json(package_path, new_version) results.append((package_path, result)) + for workspace_path in NPM_WORKSPACES: + run_npm_install(workspace_path) + run_yarn_install(workspace_path) return results @@ -134,6 +168,7 @@ def run_cargo_update(): """Run cargo update to update the Cargo.lock file.""" try: # Run cargo update showing its output with verbose flag + print("Info: run cargo update") subprocess.run(["cargo", "update", "--workspace", "--verbose"], check=True) return True except Exception: @@ -150,11 +185,14 @@ def create_git_commit_and_tag(version): for package_path in NPM_PACKAGES: package_json = f"{package_path}/package.json" package_lock = f"{package_path}/package-lock.json" + yarn_lock = f"{package_path}/yarn.lock" if os.path.exists(package_json): files_to_add.append(package_json) if os.path.exists(package_lock): files_to_add.append(package_lock) + if os.path.exists(yarn_lock): + files_to_add.append(yarn_lock) # Add each file individually for file in files_to_add: diff --git a/simulator-docker-runner/docker-entrypoint.simulator.ts b/simulator-docker-runner/docker-entrypoint.simulator.ts index 9d59c8e8b..c76506d1a 100644 --- a/simulator-docker-runner/docker-entrypoint.simulator.ts +++ b/simulator-docker-runner/docker-entrypoint.simulator.ts @@ -171,10 +171,16 @@ while (new Date().getTime() - startTime.getTime() < TIME_LIMIT_MINUTES * 60 * 10 args.push('--seed', seed); // Bugbase wants to have .git available, so we disable it args.push("--disable-bugbase"); + + if (Math.random() < 0.5) { + args.push("--profile", "faultless"); + } + args.push(...["--minimum-tests", "100", "--maximum-tests", "1000"]); const loop = args.includes("loop") ? [] : ["loop", "-n", "10", "--short-circuit"] args.push(...loop); + console.log(`[${timestamp}]: Running "limbo_sim ${args.join(" ")}" - (seed ${seed}, run number ${runNumber})`); const issuePosted = await run(seed, "limbo_sim", args); diff --git a/simulator/profiles/mod.rs b/simulator/profiles/mod.rs index 633bb3750..758c5f4b2 100644 --- a/simulator/profiles/mod.rs +++ b/simulator/profiles/mod.rs @@ -93,7 +93,7 @@ impl Profile { }, query: QueryProfile { create_table_weight: 0, - create_index_weight: 0, + create_index_weight: 4, ..Default::default() }, ..Default::default() diff --git a/sql_generation/generation/predicate/binary.rs b/sql_generation/generation/predicate/binary.rs index a5901a9f8..5047ff706 100644 --- a/sql_generation/generation/predicate/binary.rs +++ b/sql_generation/generation/predicate/binary.rs @@ -259,16 +259,16 @@ impl SimplePredicate { table: &T, row: &[SimValue], ) -> Self { - // Pick a random column - let columns = table.columns().collect::>(); - let column_index = rng.random_range(0..columns.len()); - let column = columns[column_index]; - let column_value = &row[column_index]; - let table_name = column.table_name; // Avoid creation of NULLs if row.is_empty() { return SimplePredicate(Predicate(Expr::Literal(SimValue::TRUE.into()))); } + // Pick a random column + let columns = table.columns().collect::>(); + let column_index = rng.random_range(0..row.len()); + let column = columns[column_index]; + let column_value = &row[column_index]; + let table_name = column.table_name; let expr = one_of( vec![ @@ -317,16 +317,16 @@ impl SimplePredicate { table: &T, row: &[SimValue], ) -> Self { - let columns = table.columns().collect::>(); - // Pick a random column - let column_index = rng.random_range(0..columns.len()); - let column = columns[column_index]; - let column_value = &row[column_index]; - let table_name = column.table_name; // Avoid creation of NULLs if row.is_empty() { return SimplePredicate(Predicate(Expr::Literal(SimValue::FALSE.into()))); } + let columns = table.columns().collect::>(); + // Pick a random column + let column_index = rng.random_range(0..row.len()); + let column = columns[column_index]; + let column_value = &row[column_index]; + let table_name = column.table_name; let expr = one_of( vec![ diff --git a/sql_generation/generation/predicate/unary.rs b/sql_generation/generation/predicate/unary.rs index bfcd1cff0..1cc0e0d24 100644 --- a/sql_generation/generation/predicate/unary.rs +++ b/sql_generation/generation/predicate/unary.rs @@ -124,12 +124,11 @@ impl SimplePredicate { pub fn true_unary( rng: &mut R, context: &C, - table: &T, + _table: &T, row: &[SimValue], ) -> Self { - let columns = table.columns().collect::>(); // Pick a random column - let column_index = rng.random_range(0..columns.len()); + let column_index = rng.random_range(0..row.len()); let column_value = &row[column_index]; let num_retries = row.len(); // Avoid creation of NULLs @@ -191,18 +190,17 @@ impl SimplePredicate { pub fn false_unary( rng: &mut R, context: &C, - table: &T, + _table: &T, row: &[SimValue], ) -> Self { - let columns = table.columns().collect::>(); - // Pick a random column - let column_index = rng.random_range(0..columns.len()); - let column_value = &row[column_index]; - let num_retries = row.len(); // Avoid creation of NULLs if row.is_empty() { return SimplePredicate(Predicate(Expr::Literal(SimValue::FALSE.into()))); } + // Pick a random column + let column_index = rng.random_range(0..row.len()); + let column_value = &row[column_index]; + let num_retries = row.len(); let expr = backtrack( vec![ // ( diff --git a/sql_generation/model/query/select.rs b/sql_generation/model/query/select.rs index 055db1acc..f9c92cc8f 100644 --- a/sql_generation/model/query/select.rs +++ b/sql_generation/model/query/select.rs @@ -229,7 +229,7 @@ impl FromClause { let mut join_table = JoinTable { tables: vec![first_table.clone()], - rows: Vec::new(), + rows: first_table.rows.clone(), }; for join in &self.joins { diff --git a/stress/main.rs b/stress/main.rs index f1a335fae..de9aaf5fa 100644 --- a/stress/main.rs +++ b/stress/main.rs @@ -519,7 +519,7 @@ async fn main() -> Result<(), Box> { let mut conn = db.lock().await.connect()?; println!("\rExecuting queries..."); for query_index in 0..nr_iterations { - if gen_bool(0.001) { + if gen_bool(0.001) && false { if opts.verbose { println!("Reopening database"); } @@ -531,7 +531,7 @@ async fn main() -> Result<(), Box> { } *db_guard = builder.build().await?; conn = db_guard.connect()?; - } else if gen_bool(0.01) { + } else if gen_bool(0.01) && false { // Reconnect to the database if opts.verbose { println!("Reconnecting to database"); diff --git a/sync/javascript/package.json b/sync/javascript/package.json index 90b955423..11a91c979 100644 --- a/sync/javascript/package.json +++ b/sync/javascript/package.json @@ -1,6 +1,6 @@ { "name": "@tursodatabase/sync", - "version": "0.1.5-pre.3", + "version": "0.1.5-pre.5", "repository": { "type": "git", "url": "https://github.com/tursodatabase/turso" diff --git a/testing/join.test b/testing/join.test index 034719b1f..e0fbd436d 100755 --- a/testing/join.test +++ b/testing/join.test @@ -329,3 +329,13 @@ do_execsql_test_on_specific_db {:memory:} next-crash { select a.x, b.x, c.x from a left join b on a.y=b.x left join c on b.y=c.x; } {1|| 2||} + +# regression test for crash in op_column +do_execsql_test_on_specific_db {:memory:} left-join-column-crash { + create table a(x int primary key,y); + create table b(x int primary key,y); + insert into a values (1,1),(2,2); + insert into b values (3,3),(4,4); + select * from a left join b on a.x < 2 where a.x < 3 and b.x < 12; +} {1|1|3|3 +1|1|4|4} \ No newline at end of file diff --git a/testing/json.test b/testing/json.test index 998cef195..781859e35 100755 --- a/testing/json.test +++ b/testing/json.test @@ -1342,3 +1342,82 @@ do_execsql_test json_each_json_extract_on_value { {k3|[3]} } +do_execsql_test json-each-2arg-array-basic { + SELECT key, value, type, path, fullkey FROM json_each('{"a":[1,2,3]}', '$.a') ORDER BY key; +} { + {0|1|integer|$.a|$.a[0]} + {1|2|integer|$.a|$.a[1]} + {2|3|integer|$.a|$.a[2]} +} + +do_execsql_test json-each-2arg-object-basic { + SELECT key, value, type, path, fullkey + FROM json_each('{"obj":{"a":[1,2],"n":10,"x":"y"}}', '$.obj') + ORDER BY key; +} { + {a|[1,2]|array|$.obj|$.obj.a} + {n|10|integer|$.obj|$.obj.n} + {x|y|text|$.obj|$.obj.x} +} + +do_execsql_test json-each-2arg-root-dollar-array { + SELECT key, value, type + FROM json_each('[4,5]', '$') + ORDER BY key; +} { + {0|4|integer} + {1|5|integer} +} + +do_execsql_test json-each-2arg-start-at-primitive { + SELECT value, type, path, fullkey FROM json_each('{"a":[1,2,3]}', '$.a[1]'); +} { + {2|integer|$.a[1]|$.a[1]} +} + +do_execsql_test json-each-2arg-start-at-object-inside-array { + SELECT key, value, type, path, fullkey + FROM json_each('{"arr":[{"x":1},{"y":2}]}', '$.arr[1]'); +} { + {y|2|integer|$.arr[1]|$.arr[1].y} +} + +do_execsql_test json-each-2arg-nonexistent-path-returns-no-rows { + SELECT count(*) FROM json_each('{"a":1}', '$.missing'); +} {{0}} + +do_execsql_test json-each-2arg-empty-array { + SELECT count(*) FROM json_each('{"a":[]}', '$.a'); +} {{0}} + +do_execsql_test json-each-2arg-empty-object { + SELECT count(*) FROM json_each('{"o":{}}', '$.o'); +} {{0}} + +do_execsql_test json-each-2arg-bools-and-null { + SELECT typeof(value), type + FROM json_each('{"a":[null,true,false]}', '$.a') + ORDER BY key; +} { + {null|null} + {integer|true} + {integer|false} +} + +do_execsql_test json-each-2arg-primitive-key-null { + SELECT typeof(key), value, type, path, fullkey + FROM json_each('{"s":"hi"}', '$.s'); +} {{null|hi|text|$.s|$.s}} + +do_execsql_test json-each-2arg-negative-index-root { + SELECT key, value, type + FROM json_each('[{"a":1},{"b":2},{"c":3}]', '$[#-1]'); +} {{c|3|integer}} + +do_execsql_test_in_memory_any_error non-string-path { + SELECT * FROM json_each('{}', 123); +} + +do_execsql_test_in_memory_any_error invalid-path { + SELECT * FROM json_each('{}', '$$$'); +} diff --git a/tests/integration/common.rs b/tests/integration/common.rs index a203c29f0..8a571b8ce 100644 --- a/tests/integration/common.rs +++ b/tests/integration/common.rs @@ -208,6 +208,45 @@ pub(crate) fn limbo_exec_rows( rows } +pub(crate) fn limbo_exec_rows_fallible( + _db: &TempDatabase, + conn: &Arc, + query: &str, +) -> Result>, turso_core::LimboError> { + let mut stmt = conn.prepare(query)?; + let mut rows = Vec::new(); + 'outer: loop { + let row = loop { + let result = stmt.step()?; + match result { + turso_core::StepResult::Row => { + let row = stmt.row().unwrap(); + break row; + } + turso_core::StepResult::IO => { + stmt.run_once()?; + continue; + } + + turso_core::StepResult::Done => break 'outer, + r => panic!("unexpected result {r:?}: expecting single row"), + } + }; + let row = row + .get_values() + .map(|x| match x { + turso_core::Value::Null => rusqlite::types::Value::Null, + turso_core::Value::Integer(x) => rusqlite::types::Value::Integer(*x), + turso_core::Value::Float(x) => rusqlite::types::Value::Real(*x), + turso_core::Value::Text(x) => rusqlite::types::Value::Text(x.as_str().to_string()), + turso_core::Value::Blob(x) => rusqlite::types::Value::Blob(x.to_vec()), + }) + .collect(); + rows.push(row); + } + Ok(rows) +} + pub(crate) fn limbo_exec_rows_error( _db: &TempDatabase, conn: &Arc, diff --git a/tests/integration/fuzz/mod.rs b/tests/integration/fuzz/mod.rs index be75377de..283dab940 100644 --- a/tests/integration/fuzz/mod.rs +++ b/tests/integration/fuzz/mod.rs @@ -10,7 +10,10 @@ mod tests { use rusqlite::{params, types::Value}; use crate::{ - common::{limbo_exec_rows, rng_from_time, sqlite_exec_rows, TempDatabase}, + common::{ + limbo_exec_rows, limbo_exec_rows_fallible, rng_from_time, sqlite_exec_rows, + TempDatabase, + }, fuzz::grammar_generator::{const_str, rand_int, rand_str, GrammarGenerator}, }; @@ -504,6 +507,136 @@ mod tests { } } + #[test] + /// Create a table with a random number of columns and indexes, and then randomly update or delete rows from the table. + /// Verify that the results are the same for SQLite and Turso. + pub fn table_index_mutation_fuzz() { + let _ = env_logger::try_init(); + let (mut rng, seed) = rng_from_time(); + println!("index_scan_single_key_mutation_fuzz seed: {seed}"); + + const OUTER_ITERATIONS: usize = 30; + for i in 0..OUTER_ITERATIONS { + println!( + "table_index_mutation_fuzz iteration {}/{}", + i + 1, + OUTER_ITERATIONS + ); + let limbo_db = TempDatabase::new_empty(true); + let sqlite_db = TempDatabase::new_empty(true); + let num_cols = rng.random_range(1..=10); + let table_def = (0..num_cols) + .map(|i| format!("c{i} INTEGER")) + .collect::>(); + let table_def = table_def.join(", "); + let table_def = format!("CREATE TABLE t ({table_def})"); + + let num_indexes = rng.random_range(0..=num_cols); + let indexes = (0..num_indexes) + .map(|i| format!("CREATE INDEX idx_{i} ON t(c{i})")) + .collect::>(); + + // Create tables and indexes in both databases + let limbo_conn = limbo_db.connect_limbo(); + limbo_exec_rows(&limbo_db, &limbo_conn, &table_def); + for t in indexes.iter() { + limbo_exec_rows(&limbo_db, &limbo_conn, t); + } + + let sqlite_conn = rusqlite::Connection::open(sqlite_db.path.clone()).unwrap(); + sqlite_conn.execute(&table_def, params![]).unwrap(); + for t in indexes.iter() { + sqlite_conn.execute(t, params![]).unwrap(); + } + + // Generate initial data + let num_inserts = rng.random_range(10..=1000); + let mut tuples = HashSet::new(); + while tuples.len() < num_inserts { + tuples.insert( + (0..num_cols) + .map(|_| rng.random_range(0..1000)) + .collect::>(), + ); + } + let mut insert_values = Vec::new(); + for tuple in tuples { + insert_values.push(format!( + "({})", + tuple + .iter() + .map(|x| x.to_string()) + .collect::>() + .join(", ") + )); + } + // Track executed statements in case we fail + let mut dml_statements = Vec::new(); + let insert = format!("INSERT INTO t VALUES {}", insert_values.join(", ")); + dml_statements.push(insert.clone()); + + // Insert initial data into both databases + sqlite_conn.execute(&insert, params![]).unwrap(); + limbo_exec_rows(&limbo_db, &limbo_conn, &insert); + + const COMPARISONS: [&str; 3] = ["=", "<", ">"]; + const INNER_ITERATIONS: usize = 100; + + for _ in 0..INNER_ITERATIONS { + let do_update = rng.random_range(0..2) == 0; + + let comparison = COMPARISONS[rng.random_range(0..COMPARISONS.len())]; + let affected_col = rng.random_range(0..num_cols); + let predicate_col = rng.random_range(0..num_cols); + let predicate_value = rng.random_range(0..1000); + + let query = if do_update { + let new_y = rng.random_range(0..1000); + format!("UPDATE t SET c{affected_col} = {new_y} WHERE c{predicate_col} {comparison} {predicate_value}") + } else { + format!("DELETE FROM t WHERE c{predicate_col} {comparison} {predicate_value}") + }; + + dml_statements.push(query.clone()); + + // Execute on both databases + sqlite_conn.execute(&query, params![]).unwrap(); + let limbo_res = limbo_exec_rows_fallible(&limbo_db, &limbo_conn, &query); + if let Err(e) = &limbo_res { + // print all the DDL and DML statements + println!("{table_def};"); + for t in indexes.iter() { + println!("{t};"); + } + for t in dml_statements.iter() { + println!("{t};"); + } + panic!("Error executing query: {e}"); + } + + // Verify results match exactly + let verify_query = format!( + "SELECT * FROM t ORDER BY {}", + (0..num_cols) + .map(|i| format!("c{i}")) + .collect::>() + .join(", ") + ); + let sqlite_rows = sqlite_exec_rows(&sqlite_conn, &verify_query); + let limbo_rows = limbo_exec_rows(&limbo_db, &limbo_conn, &verify_query); + + assert_eq!( + sqlite_rows, limbo_rows, + "Different results after mutation! limbo: {limbo_rows:?}, sqlite: {sqlite_rows:?}, seed: {seed}, query: {query}", + ); + + if sqlite_rows.is_empty() { + break; + } + } + } + } + #[test] pub fn compound_select_fuzz() { let _ = env_logger::try_init();