diff --git a/.github/workflows/bench-skill-rowbinary.yml b/.github/workflows/bench-skill-rowbinary.yml new file mode 100644 index 000000000..16b312939 --- /dev/null +++ b/.github/workflows/bench-skill-rowbinary.yml @@ -0,0 +1,101 @@ +name: "skill: rowbinary benchmarks" + +# Runs the RowBinary skill's benchmark suite (npm run bench) against a live +# ClickHouse server so the numbers cited externally (e.g. the @clickhouse/rowbinary +# blog post: RowBinary vs JSON, monomorphized vs API-combinator readers) have a +# timestamped, third-party-reproducible CI log + a machine-readable JSON artifact +# behind them — not just a maintainer's laptop. +# +# Decoupled from the correctness suite (tests-skill-rowbinary.yml): benchmarks are +# slower and their throughput numbers are noisy, so they shouldn't gate every PR. +# This runs on demand (workflow_dispatch) and on PRs that touch the skill or this +# workflow. + +permissions: {} +on: + workflow_dispatch: + pull_request: + paths: + - .github/workflows/bench-skill-rowbinary.yml + - skills/clickhouse-js-node-rowbinary/** + - packages/datatype-parser/** + +concurrency: + group: "${{ github.workflow }}-${{ github.ref }}" + cancel-in-progress: true + +env: + # Network resilience: npm's default of 2 fetch retries is not enough for + # the transient registry errors (ECONNRESET) we regularly hit in CI. + NPM_CONFIG_FETCH_RETRIES: "5" + NPM_CONFIG_FETCH_RETRY_MINTIMEOUT: "10000" + NPM_CONFIG_FETCH_RETRY_MAXTIMEOUT: "60000" + NPM_CONFIG_FETCH_TIMEOUT: "600000" + +jobs: + benchmarks: + timeout-minutes: 20 + runs-on: ubuntu-latest + defaults: + run: + working-directory: skills/clickhouse-js-node-rowbinary + steps: + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + + - name: Start ClickHouse (latest) in Docker + uses: hoverkraft-tech/compose-action@11beaa1c2dae4e8ed7b1665aa074723b6cecb0e4 # v3.0.0 + env: + CLICKHOUSE_VERSION: latest + with: + # The benchmarks only need the single-node HTTP server on :8123. + compose-file: "docker-compose.yml" + services: "clickhouse" + down-flags: "--volumes" + + - name: Setup NodeJS + uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + with: + node-version: 24 + + - name: Record environment (CPU, Node, ClickHouse version) + run: | + echo "Node: $(node -v)" + echo "CPU cores: $(nproc)" + grep -m1 'model name' /proc/cpuinfo || true + # The server may still be starting; poll briefly so the version is captured. + for _ in $(seq 1 30); do + chv=$(curl -s 'http://localhost:8123/?query=SELECT%20version()') + [ -n "$chv" ] && break + sleep 1 + done + echo "ClickHouse: ${chv:-}" + + # Build + pack the in-repo @clickhouse/datatype-parser so the skill is + # benchmarked against THIS checkout, not the version published to npm. The + # committed package.json keeps a published range for end users; we only + # override node_modules below (`npm install --no-save`). + - name: Pack local @clickhouse/datatype-parser + working-directory: ${{ github.workspace }} + run: | + npm ci + npm pack --workspace @clickhouse/datatype-parser --pack-destination "${{ runner.temp }}" + + - name: Install dependencies + run: npm ci + + - name: Use the local datatype-parser build + run: npm install "${{ runner.temp }}"/clickhouse-datatype-parser-*.tgz --no-save + + # Prints the human-readable tinybench summary (per-bench hz + "Nx faster" + # lines, incl. the ledger RowBinary-vs-JSON comparison) to the job log, and + # writes the same numbers as JSON for the uploaded artifact. + - name: Run benchmarks + run: npm run bench -- --outputJson "${{ runner.temp }}/rowbinary-bench-results.json" + + - name: Upload benchmark results (JSON) + if: ${{ always() }} + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + with: + name: rowbinary-bench-results + path: ${{ runner.temp }}/rowbinary-bench-results.json + if-no-files-found: error diff --git a/.github/workflows/examples.yml b/.github/workflows/examples.yml index 22757f7b1..996ae342d 100644 --- a/.github/workflows/examples.yml +++ b/.github/workflows/examples.yml @@ -17,10 +17,10 @@ on: - "tsconfig.dev.json" - "eslint.config.base.mjs" - "docker-compose.yml" - - "vitest.node.config.ts" - - "vitest.node.setup.ts" - - "vitest.web.config.ts" - - "vitest.web.setup.ts" + - "packages/client-node/vitest.config.ts" + - "packages/client-node/vitest.setup.ts" + - "packages/client-web/vitest.config.ts" + - "packages/client-web/vitest.setup.ts" - ".github/workflows/examples.yml" pull_request: paths: @@ -33,10 +33,10 @@ on: - "tsconfig.dev.json" - "eslint.config.base.mjs" - "docker-compose.yml" - - "vitest.node.config.ts" - - "vitest.node.setup.ts" - - "vitest.web.config.ts" - - "vitest.web.setup.ts" + - "packages/client-node/vitest.config.ts" + - "packages/client-node/vitest.setup.ts" + - "packages/client-web/vitest.config.ts" + - "packages/client-web/vitest.setup.ts" - ".github/workflows/examples.yml" concurrency: diff --git a/.github/workflows/tests-bun.yml b/.github/workflows/tests-bun.yml index 897bdffbf..6ab380e8d 100644 --- a/.github/workflows/tests-bun.yml +++ b/.github/workflows/tests-bun.yml @@ -16,10 +16,10 @@ on: - "tsconfig.dev.json" - "eslint.config.base.mjs" - "docker-compose.yml" - - "vitest.node.config.ts" - - "vitest.node.setup.ts" - - "vitest.web.config.ts" - - "vitest.web.setup.ts" + - "packages/client-node/vitest.config.ts" + - "packages/client-node/vitest.setup.ts" + - "packages/client-web/vitest.config.ts" + - "packages/client-web/vitest.setup.ts" - ".github/workflows/tests-bun.yml" pull_request: paths: @@ -31,10 +31,10 @@ on: - "tsconfig.dev.json" - "eslint.config.base.mjs" - "docker-compose.yml" - - "vitest.node.config.ts" - - "vitest.node.setup.ts" - - "vitest.web.config.ts" - - "vitest.web.setup.ts" + - "packages/client-node/vitest.config.ts" + - "packages/client-node/vitest.setup.ts" + - "packages/client-web/vitest.config.ts" + - "packages/client-web/vitest.setup.ts" - ".github/workflows/tests-bun.yml" concurrency: @@ -42,23 +42,6 @@ concurrency: cancel-in-progress: true jobs: - common-unit-tests: - timeout-minutes: 5 - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - - - name: Setup Bun - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 - - - name: Install dependencies - run: | - bun install - - - name: Run common unit tests - run: | - npm run test:common:unit:bun - node-unit-tests: timeout-minutes: 5 runs-on: ubuntu-latest diff --git a/.github/workflows/tests-dist.yml b/.github/workflows/tests-dist.yml index 49279e0cd..70f5ba967 100644 --- a/.github/workflows/tests-dist.yml +++ b/.github/workflows/tests-dist.yml @@ -16,10 +16,10 @@ on: - "tsconfig.dev.json" - "eslint.config.base.mjs" - "docker-compose.yml" - - "vitest.node.config.ts" - - "vitest.node.setup.ts" - - "vitest.web.config.ts" - - "vitest.web.setup.ts" + - "packages/client-node/vitest.config.ts" + - "packages/client-node/vitest.setup.ts" + - "packages/client-web/vitest.config.ts" + - "packages/client-web/vitest.setup.ts" - ".github/workflows/tests-dist.yml" pull_request: paths: @@ -31,10 +31,10 @@ on: - "tsconfig.dev.json" - "eslint.config.base.mjs" - "docker-compose.yml" - - "vitest.node.config.ts" - - "vitest.node.setup.ts" - - "vitest.web.config.ts" - - "vitest.web.setup.ts" + - "packages/client-node/vitest.config.ts" + - "packages/client-node/vitest.setup.ts" + - "packages/client-web/vitest.config.ts" + - "packages/client-web/vitest.setup.ts" - ".github/workflows/tests-dist.yml" schedule: diff --git a/.github/workflows/tests-node.yml b/.github/workflows/tests-node.yml index b509b334f..a06a8f976 100644 --- a/.github/workflows/tests-node.yml +++ b/.github/workflows/tests-node.yml @@ -16,10 +16,10 @@ on: - "tsconfig.dev.json" - "eslint.config.base.mjs" - "docker-compose.yml" - - "vitest.node.config.ts" - - "vitest.node.setup.ts" - - "vitest.web.config.ts" - - "vitest.web.setup.ts" + - "packages/client-node/vitest.config.ts" + - "packages/client-node/vitest.setup.ts" + - "packages/client-web/vitest.config.ts" + - "packages/client-web/vitest.setup.ts" - ".github/workflows/tests-node.yml" pull_request: paths: @@ -31,10 +31,10 @@ on: - "tsconfig.dev.json" - "eslint.config.base.mjs" - "docker-compose.yml" - - "vitest.node.config.ts" - - "vitest.node.setup.ts" - - "vitest.web.config.ts" - - "vitest.web.setup.ts" + - "packages/client-node/vitest.config.ts" + - "packages/client-node/vitest.setup.ts" + - "packages/client-web/vitest.config.ts" + - "packages/client-web/vitest.setup.ts" - ".github/workflows/tests-node.yml" schedule: @@ -100,48 +100,6 @@ jobs: fi cat prettier-output.txt - common-unit-tests: - timeout-minutes: 5 - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - node: [20, 22, 24, 26] - steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - - - name: Setup NodeJS ${{ matrix.node }} - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 - with: - node-version: ${{ matrix.node }} - - - name: Install dependencies - run: | - npm install - - - name: Run unit tests - run: | - npm run test:common:unit:node - - - name: Export coverage metrics - env: - COVERAGE_REPORT_NAME: ${{ github.job }} (${{ matrix.node }}) - run: | - node .scripts/export-coverage-metrics.mjs - - - name: Upload coverage to Codecov - # Codecov token is not available for Dependabot PRs or PRs from forks; skip the upload in those cases. - # Upload coverage from a single canonical combination (Node 24) so Codecov - # receives exactly one upload per flag (see codecov.yml). - if: ${{ github.triggering_actor != 'dependabot[bot]' && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) && matrix.node == 24 }} - uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v6.0.2 - with: - name: node-common-unit - flags: node-common-unit - token: ${{ secrets.CODECOV_TOKEN }} - files: ./coverage/lcov.info - fail_ci_if_error: true - unit-tests: timeout-minutes: 5 runs-on: ubuntu-latest diff --git a/.github/workflows/tests-oss-dependents.yml b/.github/workflows/tests-oss-dependents.yml index c48d22987..cf7edd61b 100644 --- a/.github/workflows/tests-oss-dependents.yml +++ b/.github/workflows/tests-oss-dependents.yml @@ -16,10 +16,10 @@ on: - "tsconfig.dev.json" - "eslint.config.base.mjs" - "docker-compose.yml" - - "vitest.node.config.ts" - - "vitest.node.setup.ts" - - "vitest.web.config.ts" - - "vitest.web.setup.ts" + - "packages/client-node/vitest.config.ts" + - "packages/client-node/vitest.setup.ts" + - "packages/client-web/vitest.config.ts" + - "packages/client-web/vitest.setup.ts" - ".github/workflows/tests-oss-dependents.yml" pull_request: paths: @@ -31,10 +31,10 @@ on: - "tsconfig.dev.json" - "eslint.config.base.mjs" - "docker-compose.yml" - - "vitest.node.config.ts" - - "vitest.node.setup.ts" - - "vitest.web.config.ts" - - "vitest.web.setup.ts" + - "packages/client-node/vitest.config.ts" + - "packages/client-node/vitest.setup.ts" + - "packages/client-web/vitest.config.ts" + - "packages/client-web/vitest.setup.ts" - ".github/workflows/tests-oss-dependents.yml" schedule: diff --git a/.github/workflows/tests-web.yml b/.github/workflows/tests-web.yml index 4fb2bae42..a3424a48e 100644 --- a/.github/workflows/tests-web.yml +++ b/.github/workflows/tests-web.yml @@ -16,10 +16,10 @@ on: - "tsconfig.dev.json" - "eslint.config.base.mjs" - "docker-compose.yml" - - "vitest.node.config.ts" - - "vitest.node.setup.ts" - - "vitest.web.config.ts" - - "vitest.web.setup.ts" + - "packages/client-node/vitest.config.ts" + - "packages/client-node/vitest.setup.ts" + - "packages/client-web/vitest.config.ts" + - "packages/client-web/vitest.setup.ts" - ".github/workflows/tests-web.yml" pull_request: paths: @@ -31,10 +31,10 @@ on: - "tsconfig.dev.json" - "eslint.config.base.mjs" - "docker-compose.yml" - - "vitest.node.config.ts" - - "vitest.node.setup.ts" - - "vitest.web.config.ts" - - "vitest.web.setup.ts" + - "packages/client-node/vitest.config.ts" + - "packages/client-node/vitest.setup.ts" + - "packages/client-web/vitest.config.ts" + - "packages/client-web/vitest.setup.ts" - ".github/workflows/tests-web.yml" schedule: @@ -59,51 +59,6 @@ env: NPM_CONFIG_FETCH_TIMEOUT: "600000" jobs: - common-unit-tests: - timeout-minutes: 5 - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - browser: [chromium, firefox] # We're not testing in WebKit atm - steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - - - name: Setup NodeJS - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 - with: - node-version: 24 - - - name: Install dependencies - run: | - npm install - npx playwright install ${{ matrix.browser }} - - - name: Run unit tests (${{ matrix.browser }}) - env: - BROWSER: ${{ matrix.browser }} - run: | - npm run test:common:unit:web - - - name: Export coverage metrics - env: - COVERAGE_REPORT_NAME: ${{ github.job }} (${{ matrix.browser }}) - run: | - node .scripts/export-coverage-metrics.mjs - - - name: Upload coverage to Codecov - # Codecov token is not available for Dependabot PRs or PRs from forks; skip the upload in those cases. - # Upload coverage from a single canonical combination (Chromium) so Codecov - # receives exactly one upload per flag (see codecov.yml). - if: ${{ github.triggering_actor != 'dependabot[bot]' && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) && matrix.browser == 'chromium' }} - uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v6.0.2 - with: - name: web-common-unit - flags: web-common-unit - token: ${{ secrets.CODECOV_TOKEN }} - files: ./coverage/lcov.info - fail_ci_if_error: true - all-tests-local-single-node: timeout-minutes: 5 runs-on: ubuntu-latest diff --git a/.gitignore b/.gitignore index aed1a6009..4af759539 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,5 @@ out coverage coverage-web .nyc_output -packages/*/README.md packages/*/LICENSE packages/*/skills/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2c3ef219b..4df45ab5a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -53,13 +53,12 @@ everyone in the community can safely benefit from your contribution. We use [Vitest](https://vitest.dev/) as the test runner and the testing framework. It covers a variety of testing needs, including unit and integration tests, and supports both Node.js, Web environments and edge runtimes. -The repository uses three consolidated Vitest configuration files: +The repository keeps two Vitest configuration files, embedded in the client packages: -- `vitest.client-common.config.ts` - Tests for the common client package -- `vitest.node.config.ts` - Tests for the Node.js client package -- `vitest.web.config.ts` - Tests for the Web client package +- `packages/client-node/vitest.config.ts` - Tests for the Node.js client package +- `packages/client-web/vitest.config.ts` - Tests for the Web client package -Each config supports multiple test modes controlled by the `TEST_MODE` environment variable, allowing different test scenarios (unit, integration, TLS, etc.) to be run with a single configuration file. +The shared (common) sources live in `packages/client-common` and are bundled into both clients; the common specs are run as part of the Node.js and Web test suites, so the common code is covered without a separate config. Each config supports multiple test modes controlled by the `TEST_MODE` environment variable, allowing different test scenarios (unit, integration, TLS, etc.) to be run with a single configuration file. ### Type checking and linting @@ -89,11 +88,11 @@ treat all warnings as errors that must be fixed before merging. Does not require a running ClickHouse server. ```bash -# Run common unit tests -npm run test:common:unit - -# Run Node.js unit tests +# Run Node.js unit tests (also runs the common unit tests) npm run test:node:unit + +# Run Web unit tests (also runs the common unit tests) +npm run test:web:unit ``` ### Running integration tests diff --git a/codecov.yml b/codecov.yml index f5fbfcea2..88e312ce9 100644 --- a/codecov.yml +++ b/codecov.yml @@ -16,18 +16,16 @@ coverage: # ClickHouse `latest`). # # flag workflow / job -# node-common-unit node / common-unit-tests # node-unit node / unit-tests # node-integration-single node / integration-tests-local-single-node # node-integration-cluster node / integration-tests-local-cluster # node-integration-cloud node / integration-tests-cloud -# web-common-unit web / common-unit-tests # web-all-single web / all-tests-local-single-node # web-integration-cluster web / integration-tests-local-cluster # web-integration-cloud web / integration-tests-cloud -# => 9 uploads total (one per flag) +# => 7 uploads total (one per flag) # -# `after_n_builds` therefore equals the number of flags (9). When a flag is +# `after_n_builds` therefore equals the number of flags (7). When a flag is # added or removed, update this value and the `individual_flags` list to match. codecov: # Wait for the other CI checks to finish before notifying, in addition to the @@ -36,11 +34,11 @@ codecov: wait_for_ci: true # Total number of expected uploads before Codecov posts the final commit # status/notification: one upload per flag (see the table above). - after_n_builds: 9 + after_n_builds: 7 comment: # Wait for all uploads before posting/updating the PR comment. - after_n_builds: 9 + after_n_builds: 7 flag_management: default_rules: @@ -49,12 +47,10 @@ flag_management: # flag uploads exactly once, so per-flag statuses post after a single build. carryforward: true individual_flags: - - name: node-common-unit - name: node-unit - name: node-integration-single - name: node-integration-cluster - name: node-integration-cloud - - name: web-common-unit - name: web-all-single - name: web-integration-cluster - name: web-integration-cloud diff --git a/package.json b/package.json index 764d19367..8a465a4b2 100644 --- a/package.json +++ b/package.json @@ -24,29 +24,24 @@ "prettify": "prettier --write .", "prettier:check": "prettier --check .", "test": "echo -e \"Please specify a test script to run. See \\033[1mnpm run\\033[0m for reference.\" && exit 1", - "test:common:unit:node": "CLICKHOUSE_TEST_SKIP_INIT=1 TEST_MODE=common vitest -c vitest.node.config.ts", - "test:common:unit:bun": "CLICKHOUSE_TEST_SKIP_INIT=1 TEST_MODE=common bun --bun vitest -c vitest.node.config.ts", - "test:common:unit:web": "CLICKHOUSE_TEST_SKIP_INIT=1 TEST_MODE=common vitest -c vitest.web.config.ts", - "test:common:integration:node": "TEST_MODE=common-integration vitest -c vitest.node.config.ts", - "test:common:integration:web": "TEST_MODE=common-integration vitest -c vitest.web.config.ts", - "test:node:unit": "CLICKHOUSE_TEST_SKIP_INIT=1 TEST_MODE=unit vitest -c vitest.node.config.ts", - "test:node:unit:bun": "CLICKHOUSE_TEST_SKIP_INIT=1 TEST_MODE=unit bun --bun vitest -c vitest.node.config.ts", - "test:node:integration:tls": "TEST_MODE=tls vitest -c vitest.node.config.ts", - "test:node:integration": "TEST_MODE=integration vitest -c vitest.node.config.ts", - "test:node:integration:dist": "npm run build && TEST_TARGET=dist TEST_MODE=integration vitest -c vitest.node.config.ts", - "test:node:oss-dependents": "TEST_MODE=oss-dependents vitest -c vitest.node.config.ts", - "test:node:integration:local_cluster": "CLICKHOUSE_TEST_ENVIRONMENT=local_cluster TEST_MODE=integration vitest -c vitest.node.config.ts", - "test:node:integration:cloud": "CLICKHOUSE_TEST_ENVIRONMENT=cloud TEST_MODE=integration vitest -c vitest.node.config.ts", - "test:node:all": "TEST_MODE=all vitest -c vitest.node.config.ts", - "test:node:coverage": "VITEST_COVERAGE=true TEST_MODE=all vitest -c vitest.node.config.ts", - "test:web:unit": "CLICKHOUSE_TEST_SKIP_INIT=1 TEST_MODE=unit vitest -c vitest.web.config.ts", - "test:web:integration": "TEST_MODE=integration vitest -c vitest.web.config.ts", - "test:web:integration:dist": "npm run build && TEST_TARGET=dist TEST_MODE=integration vitest -c vitest.web.config.ts", - "test:web:integration:local_cluster": "TEST_MODE=integration CLICKHOUSE_TEST_ENVIRONMENT=local_cluster vitest -c vitest.web.config.ts", - "test:web:integration:cloud": "TEST_MODE=integration CLICKHOUSE_TEST_ENVIRONMENT=cloud vitest -c vitest.web.config.ts", - "test:web:integration:cloud:jwt": "TEST_MODE=jwt CLICKHOUSE_TEST_ENVIRONMENT=cloud vitest -c vitest.web.config.ts", - "test:web:all": "TEST_MODE=all vitest -c vitest.web.config.ts", - "test:web:coverage": "VITEST_COVERAGE=true TEST_MODE=all vitest -c vitest.web.config.ts", + "test:node:unit": "npm --prefix packages/client-node run test:unit", + "test:node:unit:bun": "npm --prefix packages/client-node run test:unit:bun", + "test:node:integration:tls": "npm --prefix packages/client-node run test:integration:tls", + "test:node:integration": "npm --prefix packages/client-node run test:integration", + "test:node:integration:dist": "npm --prefix packages/client-node run test:integration:dist", + "test:node:oss-dependents": "npm --prefix packages/client-node run test:oss-dependents", + "test:node:integration:local_cluster": "npm --prefix packages/client-node run test:integration:local_cluster", + "test:node:integration:cloud": "npm --prefix packages/client-node run test:integration:cloud", + "test:node:all": "npm --prefix packages/client-node run test:all", + "test:node:coverage": "npm --prefix packages/client-node run test:coverage", + "test:web:unit": "npm --prefix packages/client-web run test:unit", + "test:web:integration": "npm --prefix packages/client-web run test:integration", + "test:web:integration:dist": "npm --prefix packages/client-web run test:integration:dist", + "test:web:integration:local_cluster": "npm --prefix packages/client-web run test:integration:local_cluster", + "test:web:integration:cloud": "npm --prefix packages/client-web run test:integration:cloud", + "test:web:integration:cloud:jwt": "npm --prefix packages/client-web run test:integration:cloud:jwt", + "test:web:all": "npm --prefix packages/client-web run test:all", + "test:web:coverage": "npm --prefix packages/client-web run test:coverage", "//": "See https://github.com/kylebarron/parquet-wasm/issues/798", "postinstall": "cd node_modules/parquet-wasm && npm pkg delete type", "prepare": "husky" diff --git a/packages/client-common/README.md b/packages/client-common/README.md new file mode 100644 index 000000000..b7cb27636 --- /dev/null +++ b/packages/client-common/README.md @@ -0,0 +1,55 @@ +# @clickhouse/client-common + +> [!WARNING] +> **This package is deprecated and is no longer maintained as a dependency.** +> It is no longer used by [`@clickhouse/client`](https://www.npmjs.com/package/@clickhouse/client) +> (Node.js) or [`@clickhouse/client-web`](https://www.npmjs.com/package/@clickhouse/client-web) +> (Web), and there is **no replacement package** to depend on. Do not add this +> package to new projects. +> +> - Building a ClickHouse app on **Node.js**? Install +> [`@clickhouse/client`](https://www.npmjs.com/package/@clickhouse/client). +> - Building for the **browser / edge runtimes**? Install +> [`@clickhouse/client-web`](https://www.npmjs.com/package/@clickhouse/client-web). + +## What this package was for + +Historically, the shared code between `@clickhouse/client` (Node.js) and +`@clickhouse/client-web` lived in this third published package, +`@clickhouse/client-common`, which both of them depended on. It exposed the +shared types and the base framework that were also intended to be the foundation +for building **custom client implementations** for alternative runtimes (such as +Bun or Cloudflare Workers) or alternative protocols (such as the native +ClickHouse protocol or gRPC over a proxy). + +## Why it is deprecated + +The shared-package approach is being retired to simplify versioning across the +packages and to avoid the bundling/duplication issues that several downstream +users have hit. + +What this means in practice: + +- The shared code is **not** being moved into a new shared package; there is no + replacement to depend on. +- Instead, the shared code is now inlined / co-located inside each runtime + package (`@clickhouse/client`, `@clickhouse/client-web`, …). Going forward, + each runtime package is **self-contained** and published independently. + +## Building a client for an alternative runtime or protocol + +The new, recommended approach is to **fork an existing in-tree client package and +iterate on it** — copy the pieces you need into your own package the same way +`client-node` and `client-web` do, rather than depending on a shared package. + +See +[Building specialized clients for alternative runtimes and protocols](https://github.com/ClickHouse/clickhouse-js/blob/main/ALTERNATIVE_CLIENTS.md) +for the full guide. + +## Changelog + +See [`CHANGELOG.md`](https://github.com/ClickHouse/clickhouse-js/blob/main/packages/client-common/CHANGELOG.md). + +## License + +[Apache 2.0](https://github.com/ClickHouse/clickhouse-js/blob/main/LICENSE) diff --git a/packages/client-common/package.json b/packages/client-common/package.json index e5893e09a..cd04443af 100644 --- a/packages/client-common/package.json +++ b/packages/client-common/package.json @@ -22,7 +22,7 @@ ], "scripts": { "pack": "npm pack", - "prepack": "cp ../../README.md ../../LICENSE .", + "prepack": "cp ../../LICENSE .", "typecheck": "tsc --noEmit", "lint": "eslint --max-warnings=0 .", "lint:fix": "eslint . --fix", diff --git a/packages/client-node/CHANGELOG.md b/packages/client-node/CHANGELOG.md index 7ae3e0373..faa822daa 100644 --- a/packages/client-node/CHANGELOG.md +++ b/packages/client-node/CHANGELOG.md @@ -1,3 +1,11 @@ +# 1.23.1 + +## Bug Fixes + +- Re-export `EXCEPTION_TAG_HEADER_NAME` and `extractErrorAtTheEndOfChunk` from `@clickhouse/client`. Both are part of the (now deprecated) `@clickhouse/client-common` public API but were missed when its surface was bundled into and re-exported from the client packages in 1.23.0 ([#845]). Reported downstream by Langfuse. ([#935]) + +[#935]: https://github.com/ClickHouse/clickhouse-js/pull/935 + # 1.23.0 ## Migration Notes diff --git a/packages/client-node/README.md b/packages/client-node/README.md new file mode 100644 index 000000000..1b2bb94cd --- /dev/null +++ b/packages/client-node/README.md @@ -0,0 +1,89 @@ +# @clickhouse/client + +Official Node.js client for [ClickHouse](https://clickhouse.com/), written +purely in TypeScript and thoroughly tested against actual ClickHouse versions. + +It is built on top of the Node.js [HTTP](https://nodejs.org/api/http.html) and +[Stream](https://nodejs.org/api/stream.html) APIs and supports streaming for +both selects and inserts. The client has zero external dependencies and is +optimized for maximum performance. + +> Looking for a browser / edge runtime (Cloudflare Workers, etc.) instead? Use +> [`@clickhouse/client-web`](https://www.npmjs.com/package/@clickhouse/client-web). + +## Installation + +```sh +npm i @clickhouse/client +``` + +## Environment requirements + +Node.js must be available in the environment to run the client. The client is +compatible with all the [maintained](https://github.com/nodejs/release#readme) +Node.js releases. + +| Node.js version | Supported? | +| --------------- | ---------- | +| 26.x | ✔ | +| 24.x | ✔ | +| 22.x | ✔ | +| 20.x | ✔ | + +If using TypeScript, version +[4.5](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-5.html) +or above is required to enable +[inline import and export syntax](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-5.html#type-modifiers-on-import-names). + +## Compatibility with ClickHouse + +| Client version | ClickHouse | +| -------------- | ---------- | +| 1.12.0+ | 24.8+ | + +The client may work with older versions too; however, this is best-effort +support and is not guaranteed. + +## Quick start + +```ts +import { createClient } from "@clickhouse/client"; + +const client = createClient({ + url: process.env.CLICKHOUSE_URL ?? "http://localhost:8123", + username: process.env.CLICKHOUSE_USER ?? "default", + password: process.env.CLICKHOUSE_PASSWORD ?? "", +}); + +const resultSet = await client.query({ + query: "SELECT * FROM system.tables", + format: "JSONEachRow", +}); + +const tables = await resultSet.json(); +console.log(tables); + +await client.close(); +``` + +See more examples in the +[examples directory](https://github.com/ClickHouse/clickhouse-js/tree/main/examples). + +## Documentation + +See the [ClickHouse website](https://clickhouse.com/docs/integrations/javascript) +for the full documentation. + +## Changelog + +See [`CHANGELOG.md`](https://github.com/ClickHouse/clickhouse-js/blob/main/packages/client-node/CHANGELOG.md). + +## Contact us + +If you have any questions or need help, feel free to reach out to us in the +[Community Slack](https://clickhouse.com/slack) (`#clickhouse-js` channel) or +via [GitHub issues](https://github.com/ClickHouse/clickhouse-js/issues). + +## License + +[Apache 2.0](https://github.com/ClickHouse/clickhouse-js/blob/main/LICENSE) diff --git a/packages/client-node/eslint.config.mjs b/packages/client-node/eslint.config.mjs index d142e6c9f..cc8c651d5 100644 --- a/packages/client-node/eslint.config.mjs +++ b/packages/client-node/eslint.config.mjs @@ -19,8 +19,9 @@ export default defineConfig( ignores: [ "./__tests__/**/*.ts", "eslint.config.mjs", - "vitest.*.config.ts", - "vitest.*.setup.ts", + "vitest.config.ts", + "vitest.setup.ts", + "vitest.otel.js", "coverage", "out", "dist", diff --git a/packages/client-node/package.json b/packages/client-node/package.json index d8e0941e9..21495a03a 100644 --- a/packages/client-node/package.json +++ b/packages/client-node/package.json @@ -42,11 +42,21 @@ }, "scripts": { "pack": "npm pack", - "prepack": "rm -rf skills && cp ../../README.md ../../LICENSE . && cp -r ../../skills . && RBP=skills/clickhouse-js-node-rowbinary && rm -rf $RBP/tests $RBP/node_modules $RBP/dist $RBP/package.json $RBP/package-lock.json $RBP/tsconfig.json $RBP/tsconfig.build.json $RBP/vitest.config.ts $RBP/.gitignore $RBP/LICENSE $RBP/eval_result*.md", + "prepack": "rm -rf skills && cp ../../LICENSE . && cp -r ../../skills . && RBP=skills/clickhouse-js-node-rowbinary && rm -rf $RBP/tests $RBP/node_modules $RBP/dist $RBP/package.json $RBP/package-lock.json $RBP/tsconfig.json $RBP/tsconfig.build.json $RBP/vitest.config.ts $RBP/.gitignore $RBP/LICENSE $RBP/eval_result*.md", "typecheck": "tsc --noEmit", "lint": "eslint --max-warnings=0 .", "lint:fix": "eslint . --fix", - "build": "rm -rf dist; tsc" + "build": "rm -rf dist; tsc", + "test:unit": "CLICKHOUSE_TEST_SKIP_INIT=1 TEST_MODE=unit vitest", + "test:unit:bun": "CLICKHOUSE_TEST_SKIP_INIT=1 TEST_MODE=unit bun --bun vitest", + "test:integration": "TEST_MODE=integration vitest", + "test:integration:tls": "TEST_MODE=tls vitest", + "test:integration:dist": "npm --prefix ../.. run build && TEST_TARGET=dist TEST_MODE=integration vitest", + "test:integration:local_cluster": "CLICKHOUSE_TEST_ENVIRONMENT=local_cluster TEST_MODE=integration vitest", + "test:integration:cloud": "CLICKHOUSE_TEST_ENVIRONMENT=cloud TEST_MODE=integration vitest", + "test:oss-dependents": "TEST_MODE=oss-dependents vitest", + "test:all": "TEST_MODE=all vitest", + "test:coverage": "VITEST_COVERAGE=true TEST_MODE=all vitest" }, "dependencies": {}, "devDependencies": { diff --git a/packages/client-node/src/index.ts b/packages/client-node/src/index.ts index 638f85035..9d3938272 100644 --- a/packages/client-node/src/index.ts +++ b/packages/client-node/src/index.ts @@ -93,6 +93,8 @@ import { ClickHouseSpanStatusCode as ClickHouseSpanStatusCode_, ClickHouseSpanKind as ClickHouseSpanKind_, defaultJSONHandling as defaultJSONHandling_, + EXCEPTION_TAG_HEADER_NAME as EXCEPTION_TAG_HEADER_NAME_, + extractErrorAtTheEndOfChunk as extractErrorAtTheEndOfChunk_, } from "./common/index"; export const ClickHouseError = ClickHouseError_; @@ -121,3 +123,5 @@ export const ClickHouseSpanNames = ClickHouseSpanNames_; export const ClickHouseSpanStatusCode = ClickHouseSpanStatusCode_; export const ClickHouseSpanKind = ClickHouseSpanKind_; export const defaultJSONHandling = defaultJSONHandling_; +export const EXCEPTION_TAG_HEADER_NAME = EXCEPTION_TAG_HEADER_NAME_; +export const extractErrorAtTheEndOfChunk = extractErrorAtTheEndOfChunk_; diff --git a/vitest.node.config.ts b/packages/client-node/vitest.config.ts similarity index 89% rename from vitest.node.config.ts rename to packages/client-node/vitest.config.ts index 88268c89e..f29503b36 100644 --- a/vitest.node.config.ts +++ b/packages/client-node/vitest.config.ts @@ -1,17 +1,27 @@ import { defineConfig } from "vitest/config"; +import { fileURLToPath } from "node:url"; + +// Embedded in the node client package, but rooted at the repo so the shared +// (common) sources and specs are reachable. The node and web packages run the +// common tests so the common code is exercised and shows up in coverage. +const root = fileURLToPath(new URL("../..", import.meta.url)); + +// The package scripts run vitest via `npm --prefix packages/client-node`, which +// sets the process cwd to the package dir. Some specs read fixtures/certs via +// repo-root-relative paths (e.g. node_streaming_e2e, tls), so pin the cwd to the +// repo root to match `root` above. Workers inherit this cwd when they spawn. +process.chdir(root); const testMode = process.env.TEST_MODE; if ( testMode !== "unit" && testMode !== "integration" && testMode !== "tls" && - testMode !== "common" && - testMode !== "common-integration" && testMode !== "oss-dependents" && testMode !== "all" ) { throw new Error( - `Unsupported TEST_MODE: [${testMode}]. Supported modes are: unit, integration, tls, common, common-integration, oss-dependents, all.`, + `Unsupported TEST_MODE: [${testMode}]. Supported modes are: unit, integration, tls, oss-dependents, all.`, ); } @@ -37,27 +47,22 @@ if (testTarget !== "src" && testTarget !== "dist") { const collections = { unit: [ + "packages/client-common/__tests__/unit/*.test.ts", + "packages/client-common/__tests__/utils/*.test.ts", "packages/client-node/__tests__/unit/*.test.ts", "packages/client-node/__tests__/utils/*.test.ts", ], integration: [ - "packages/client-node/__tests__/integration/*.test.ts", "packages/client-common/__tests__/integration/*.test.ts", + "packages/client-node/__tests__/integration/*.test.ts", ], // TLS tests require a specific environment setup // This list is integration + TLS tests tls: [ - "packages/client-node/__tests__/integration/*.test.ts", "packages/client-common/__tests__/integration/*.test.ts", + "packages/client-node/__tests__/integration/*.test.ts", "packages/client-node/__tests__/tls/*.test.ts", ], - common: [ - "packages/client-common/__tests__/unit/*.test.ts", - "packages/client-common/__tests__/utils/*.test.ts", - ], - "common-integration": [ - "packages/client-common/__tests__/integration/*.test.ts", - ], // Runnable reproductions of how the top OSS dependents use the client. // These specs import only the public package names, so they default to // TEST_TARGET=dist (see above) and resolve to the BUILT workspace packages: @@ -78,6 +83,7 @@ const collections = { }; export default defineConfig({ + root, test: { // Increase maxWorkers to speed up integration tests // as we're not bound by the CPU here. @@ -86,7 +92,7 @@ export default defineConfig({ hookTimeout: 300_000, testTimeout: 300_000, slowTestThreshold: testMode === "unit" ? 10_000 : undefined, - setupFiles: ["vitest.node.setup.ts"], + setupFiles: ["packages/client-node/vitest.setup.ts"], include: collections[testMode], coverage: { enabled: process.env.VITEST_COVERAGE === "true", @@ -118,7 +124,7 @@ export default defineConfig({ process.env.VITEST_OTEL_ENABLED === "true" && // not set in dependabot PRs !!process.env.OTEL_EXPORTER_OTLP_ENDPOINT, - sdkPath: "./vitest.node.otel.js", + sdkPath: "./packages/client-node/vitest.otel.js", }, }, retry: process.env.CI ? 2 : 0, diff --git a/vitest.node.otel.js b/packages/client-node/vitest.otel.js similarity index 100% rename from vitest.node.otel.js rename to packages/client-node/vitest.otel.js diff --git a/vitest.node.setup.ts b/packages/client-node/vitest.setup.ts similarity index 100% rename from vitest.node.setup.ts rename to packages/client-node/vitest.setup.ts diff --git a/packages/client-web/CHANGELOG.md b/packages/client-web/CHANGELOG.md index 7ae3e0373..1883e1f6d 100644 --- a/packages/client-web/CHANGELOG.md +++ b/packages/client-web/CHANGELOG.md @@ -1,3 +1,11 @@ +# 1.23.1 + +## Bug Fixes + +- Re-export `EXCEPTION_TAG_HEADER_NAME` and `extractErrorAtTheEndOfChunk` from `@clickhouse/client-web`. Both are part of the (now deprecated) `@clickhouse/client-common` public API but were missed when its surface was bundled into and re-exported from the client packages in 1.23.0 ([#845]). Reported downstream by Langfuse. ([#935]) + +[#935]: https://github.com/ClickHouse/clickhouse-js/pull/935 + # 1.23.0 ## Migration Notes diff --git a/packages/client-web/README.md b/packages/client-web/README.md new file mode 100644 index 000000000..14b13f535 --- /dev/null +++ b/packages/client-web/README.md @@ -0,0 +1,86 @@ +# @clickhouse/client-web + +Official Web client for [ClickHouse](https://clickhouse.com/), written purely in +TypeScript and thoroughly tested against actual ClickHouse versions. + +It is built on top of the +[Fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) and +[Web Streams](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API) APIs +and supports streaming for selects. It is compatible with Chrome/Firefox +browsers and Cloudflare Workers. The client has zero external dependencies and is +optimized for maximum performance. + +> Running on Node.js? Use +> [`@clickhouse/client`](https://www.npmjs.com/package/@clickhouse/client) +> instead, which additionally supports streaming for inserts. + +## Installation + +```sh +npm i @clickhouse/client-web +``` + +## Environment requirements + +The client targets runtimes that provide the standard +[Fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) and +[Web Streams](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API) APIs, +such as modern Chrome/Firefox browsers and Cloudflare Workers. + +If using TypeScript, version +[4.5](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-5.html) +or above is required to enable +[inline import and export syntax](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-5.html#type-modifiers-on-import-names). + +## Compatibility with ClickHouse + +| Client version | ClickHouse | +| -------------- | ---------- | +| 1.12.0+ | 24.8+ | + +The client may work with older versions too; however, this is best-effort +support and is not guaranteed. + +## Quick start + +```ts +import { createClient } from "@clickhouse/client-web"; + +const client = createClient({ + url: "http://localhost:8123", + username: "default", + password: "", +}); + +const resultSet = await client.query({ + query: "SELECT * FROM system.tables", + format: "JSONEachRow", +}); + +const tables = await resultSet.json(); +console.log(tables); + +await client.close(); +``` + +See more examples in the +[examples directory](https://github.com/ClickHouse/clickhouse-js/tree/main/examples). + +## Documentation + +See the [ClickHouse website](https://clickhouse.com/docs/integrations/javascript) +for the full documentation. + +## Changelog + +See [`CHANGELOG.md`](https://github.com/ClickHouse/clickhouse-js/blob/main/packages/client-web/CHANGELOG.md). + +## Contact us + +If you have any questions or need help, feel free to reach out to us in the +[Community Slack](https://clickhouse.com/slack) (`#clickhouse-js` channel) or +via [GitHub issues](https://github.com/ClickHouse/clickhouse-js/issues). + +## License + +[Apache 2.0](https://github.com/ClickHouse/clickhouse-js/blob/main/LICENSE) diff --git a/packages/client-web/eslint.config.mjs b/packages/client-web/eslint.config.mjs index 0a540ee80..7217144d0 100644 --- a/packages/client-web/eslint.config.mjs +++ b/packages/client-web/eslint.config.mjs @@ -13,8 +13,9 @@ export default defineConfig( ignores: [ "./__tests__/**/*.ts", "eslint.config.mjs", - "vitest.*.config.ts", - "vitest.*.setup.ts", + "vitest.config.ts", + "vitest.setup.ts", + "vitest.otel.js", "coverage", "out", "dist", diff --git a/packages/client-web/package.json b/packages/client-web/package.json index dec875f8f..23e67c4d3 100644 --- a/packages/client-web/package.json +++ b/packages/client-web/package.json @@ -25,11 +25,19 @@ }, "scripts": { "pack": "npm pack", - "prepack": "cp ../../README.md ../../LICENSE .", + "prepack": "cp ../../LICENSE .", "typecheck": "tsc --noEmit", "lint": "eslint --max-warnings=0 .", "lint:fix": "eslint . --fix", - "build": "rm -rf dist; tsc" + "build": "rm -rf dist; tsc", + "test:unit": "CLICKHOUSE_TEST_SKIP_INIT=1 TEST_MODE=unit vitest", + "test:integration": "TEST_MODE=integration vitest", + "test:integration:dist": "npm --prefix ../.. run build && TEST_TARGET=dist TEST_MODE=integration vitest", + "test:integration:local_cluster": "CLICKHOUSE_TEST_ENVIRONMENT=local_cluster TEST_MODE=integration vitest", + "test:integration:cloud": "CLICKHOUSE_TEST_ENVIRONMENT=cloud TEST_MODE=integration vitest", + "test:integration:cloud:jwt": "CLICKHOUSE_TEST_ENVIRONMENT=cloud TEST_MODE=jwt vitest", + "test:all": "TEST_MODE=all vitest", + "test:coverage": "VITEST_COVERAGE=true TEST_MODE=all vitest" }, "dependencies": {} } diff --git a/packages/client-web/src/index.ts b/packages/client-web/src/index.ts index 958bdd1da..d0030758f 100644 --- a/packages/client-web/src/index.ts +++ b/packages/client-web/src/index.ts @@ -92,6 +92,8 @@ import { ClickHouseSpanStatusCode as ClickHouseSpanStatusCode_, ClickHouseSpanKind as ClickHouseSpanKind_, defaultJSONHandling as defaultJSONHandling_, + EXCEPTION_TAG_HEADER_NAME as EXCEPTION_TAG_HEADER_NAME_, + extractErrorAtTheEndOfChunk as extractErrorAtTheEndOfChunk_, } from "./common/index"; export const ClickHouseError = ClickHouseError_; @@ -120,3 +122,5 @@ export const ClickHouseSpanNames = ClickHouseSpanNames_; export const ClickHouseSpanStatusCode = ClickHouseSpanStatusCode_; export const ClickHouseSpanKind = ClickHouseSpanKind_; export const defaultJSONHandling = defaultJSONHandling_; +export const EXCEPTION_TAG_HEADER_NAME = EXCEPTION_TAG_HEADER_NAME_; +export const extractErrorAtTheEndOfChunk = extractErrorAtTheEndOfChunk_; diff --git a/vitest.web.config.ts b/packages/client-web/vitest.config.ts similarity index 86% rename from vitest.web.config.ts rename to packages/client-web/vitest.config.ts index a4080bf67..ca515c255 100644 --- a/vitest.web.config.ts +++ b/packages/client-web/vitest.config.ts @@ -2,6 +2,11 @@ import { defineConfig } from "vitest/config"; import { playwright } from "@vitest/browser-playwright"; import { fileURLToPath } from "node:url"; +// Embedded in the web client package, but rooted at the repo so the shared +// (common) sources and specs are reachable. The node and web packages run the +// common tests so the common code is exercised and shows up in coverage. +const root = fileURLToPath(new URL("../..", import.meta.url)); + const browser = process.env.BROWSER ?? "chromium"; if (browser !== "chromium" && browser !== "firefox" && browser !== "webkit") { throw new Error( @@ -14,8 +19,6 @@ if ( testMode !== "unit" && testMode !== "integration" && testMode !== "jwt" && - testMode !== "common" && - testMode !== "common-integration" && testMode !== "all" ) { throw new Error( @@ -57,13 +60,6 @@ const collections = { "packages/client-web/__tests__/integration/*.test.ts", "packages/client-web/__tests__/jwt/*.test.ts", ], - common: [ - "packages/client-common/__tests__/unit/*.test.ts", - "packages/client-common/__tests__/utils/*.test.ts", - ], - "common-integration": [ - "packages/client-common/__tests__/integration/*.test.ts", - ], all: [ "packages/client-common/__tests__/unit/*.test.ts", "packages/client-common/__tests__/utils/*.test.ts", @@ -75,6 +71,7 @@ const collections = { }; export default defineConfig({ + root, test: { // Increase maxWorkers to speed up integration tests // as we're not bound by the CPU here. @@ -83,7 +80,7 @@ export default defineConfig({ hookTimeout: 300_000, testTimeout: 300_000, slowTestThreshold: testMode === "unit" ? 10_000 : undefined, - setupFiles: ["vitest.web.setup.ts"], + setupFiles: ["packages/client-web/vitest.setup.ts"], include: collections[testMode], coverage: { enabled: process.env.VITEST_COVERAGE === "true", @@ -124,15 +121,20 @@ export default defineConfig({ process.env.VITEST_OTEL_ENABLED === "true" && // not set in dependabot PRs !!process.env.OTEL_EXPORTER_OTLP_ENDPOINT, - sdkPath: "./vitest.node.otel.js", + sdkPath: "./packages/client-node/vitest.otel.js", // According to testing, runners hang indefinitely when OTEL is enabled in browser tests, // and when they don't the exporter visibly slows the tests down (2x-5x). // Tests also crash (their iframe?) when the devtools are open in Chrome. - // browserSdkPath: './vitest.web.otel.js', + // browserSdkPath: './packages/client-web/vitest.otel.js', }, }, browser: { enabled: true, + // Run headless by default so the test runner never pops up a browser + // window (locally Vitest would otherwise launch a headed browser; it only + // defaults to headless in CI). Set BROWSER_HEADED=true to opt back into a + // visible browser, e.g. for debugging. + headless: process.env.BROWSER_HEADED !== "true", provider: playwright(), instances: [{ browser }], }, @@ -165,18 +167,18 @@ export default defineConfig({ // intact, and common-origin symbols share the client's one bundle. "@clickhouse/client-common": "@clickhouse/client-web", "@test": fileURLToPath( - new URL("./packages/client-common/__tests__", import.meta.url), + new URL("packages/client-common/__tests__", `file://${root}/`), ), } : { "@clickhouse/client-common": fileURLToPath( - new URL("./packages/client-common/src", import.meta.url), + new URL("packages/client-common/src", `file://${root}/`), ), "@clickhouse/client-web": fileURLToPath( - new URL("./packages/client-web", import.meta.url), + new URL("packages/client-web", `file://${root}/`), ), "@test": fileURLToPath( - new URL("./packages/client-common/__tests__", import.meta.url), + new URL("packages/client-common/__tests__", `file://${root}/`), ), }, }, diff --git a/vitest.web.otel.js b/packages/client-web/vitest.otel.js similarity index 100% rename from vitest.web.otel.js rename to packages/client-web/vitest.otel.js diff --git a/vitest.web.setup.ts b/packages/client-web/vitest.setup.ts similarity index 100% rename from vitest.web.setup.ts rename to packages/client-web/vitest.setup.ts