anywidget-vector 0.3.2__tar.gz → 0.4.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- anywidget_vector-0.4.1/.github/workflows/ci.yml +98 -0
- anywidget_vector-0.4.1/.github/workflows/grafeo-latest.yml +72 -0
- {anywidget_vector-0.3.2 → anywidget_vector-0.4.1}/.github/workflows/pypi.yml +20 -11
- {anywidget_vector-0.3.2 → anywidget_vector-0.4.1}/.gitignore +1 -1
- anywidget_vector-0.4.1/CHANGELOG.md +218 -0
- {anywidget_vector-0.3.2 → anywidget_vector-0.4.1}/PKG-INFO +129 -13
- {anywidget_vector-0.3.2 → anywidget_vector-0.4.1}/README.md +114 -2
- anywidget_vector-0.4.1/package-lock.json +996 -0
- anywidget_vector-0.4.1/package.json +22 -0
- {anywidget_vector-0.3.2 → anywidget_vector-0.4.1}/pyproject.toml +35 -16
- anywidget_vector-0.4.1/scripts/build-esm.mjs +65 -0
- anywidget_vector-0.4.1/scripts/vendor/build.mjs +40 -0
- anywidget_vector-0.4.1/scripts/vendor/entry.mjs +70 -0
- anywidget_vector-0.4.1/scripts/vendor/package-lock.json +506 -0
- anywidget_vector-0.4.1/scripts/vendor/package.json +15 -0
- anywidget_vector-0.4.1/src/anywidget_vector/__init__.py +13 -0
- anywidget_vector-0.4.1/src/anywidget_vector/backends/grafeo/__init__.py +23 -0
- anywidget_vector-0.4.1/src/anywidget_vector/backends/grafeo/browser.ts +65 -0
- anywidget_vector-0.4.1/src/anywidget_vector/backends/grafeo/client.py +53 -0
- anywidget_vector-0.4.1/src/anywidget_vector/backends/grafeo/converter.py +133 -0
- anywidget_vector-0.4.1/src/anywidget_vector/backends/grafeo/embed.ts +130 -0
- anywidget_vector-0.4.1/src/anywidget_vector/backends/grafeo/points.ts +119 -0
- anywidget_vector-0.3.2/src/anywidget_vector/backends/pinecone/client.js → anywidget_vector-0.4.1/src/anywidget_vector/backends/pinecone/client.ts +13 -7
- anywidget_vector-0.3.2/src/anywidget_vector/backends/qdrant/client.js → anywidget_vector-0.4.1/src/anywidget_vector/backends/qdrant/client.ts +6 -5
- anywidget_vector-0.3.2/src/anywidget_vector/backends/weaviate/client.js → anywidget_vector-0.4.1/src/anywidget_vector/backends/weaviate/client.ts +9 -10
- {anywidget_vector-0.3.2 → anywidget_vector-0.4.1}/src/anywidget_vector/demo.py +1 -1
- anywidget_vector-0.3.2/src/anywidget_vector/static/icons.js → anywidget_vector-0.4.1/src/anywidget_vector/static/icons.ts +2 -1
- anywidget_vector-0.4.1/src/anywidget_vector/ui/__init__.py +47 -0
- anywidget_vector-0.3.2/src/anywidget_vector/ui/canvas.js → anywidget_vector-0.4.1/src/anywidget_vector/ui/canvas.ts +193 -131
- anywidget_vector-0.3.2/src/anywidget_vector/ui/constants.js → anywidget_vector-0.4.1/src/anywidget_vector/ui/constants.ts +19 -3
- anywidget_vector-0.4.1/src/anywidget_vector/ui/dist/export.js +233 -0
- anywidget_vector-0.4.1/src/anywidget_vector/ui/dist/widget.js +2446 -0
- anywidget_vector-0.4.1/src/anywidget_vector/ui/export.html +43 -0
- anywidget_vector-0.4.1/src/anywidget_vector/ui/export.ts +214 -0
- anywidget_vector-0.4.1/src/anywidget_vector/ui/index.ts +171 -0
- anywidget_vector-0.3.2/src/anywidget_vector/ui/properties.js → anywidget_vector-0.4.1/src/anywidget_vector/ui/properties.ts +24 -18
- anywidget_vector-0.4.1/src/anywidget_vector/ui/query.ts +60 -0
- anywidget_vector-0.3.2/src/anywidget_vector/ui/settings.js → anywidget_vector-0.4.1/src/anywidget_vector/ui/settings.ts +15 -14
- anywidget_vector-0.3.2/src/anywidget_vector/ui/sidebar.js → anywidget_vector-0.4.1/src/anywidget_vector/ui/sidebar.ts +34 -28
- {anywidget_vector-0.3.2 → anywidget_vector-0.4.1}/src/anywidget_vector/ui/styles.css +8 -2
- anywidget_vector-0.4.1/src/anywidget_vector/ui/theme.ts +134 -0
- anywidget_vector-0.3.2/src/anywidget_vector/ui/toolbar.js → anywidget_vector-0.4.1/src/anywidget_vector/ui/toolbar.ts +13 -7
- anywidget_vector-0.4.1/src/anywidget_vector/ui/types.ts +75 -0
- anywidget_vector-0.4.1/src/anywidget_vector/ui/vendor/three.LICENSES.txt +25 -0
- anywidget_vector-0.4.1/src/anywidget_vector/ui/vendor/three.min.js +4220 -0
- anywidget_vector-0.4.1/src/anywidget_vector/ui/vendor-globals.ts +15 -0
- {anywidget_vector-0.3.2 → anywidget_vector-0.4.1}/src/anywidget_vector/widget.py +219 -335
- anywidget_vector-0.4.1/tests/conftest.py +20 -0
- anywidget_vector-0.4.1/tests/js/export.test.ts +109 -0
- anywidget_vector-0.4.1/tests/js/package-lock.json +528 -0
- anywidget_vector-0.4.1/tests/js/package.json +7 -0
- anywidget_vector-0.4.1/tests/js/render.test.ts +221 -0
- anywidget_vector-0.4.1/tests/js/wasm_smoke.ts +111 -0
- anywidget_vector-0.4.1/tests/support.py +57 -0
- anywidget_vector-0.4.1/tests/test_grafeo_backend.py +202 -0
- anywidget_vector-0.4.1/tests/test_grafeo_contract.py +383 -0
- anywidget_vector-0.4.1/tests/test_theme.py +340 -0
- anywidget_vector-0.4.1/tests/test_ui_bundle.py +566 -0
- {anywidget_vector-0.3.2 → anywidget_vector-0.4.1}/tests/test_widget.py +21 -3
- anywidget_vector-0.4.1/tests/test_widget_robustness.py +309 -0
- anywidget_vector-0.4.1/tsconfig.json +30 -0
- anywidget_vector-0.4.1/uv.lock +4228 -0
- anywidget_vector-0.3.2/.github/workflows/ci.yml +0 -71
- anywidget_vector-0.3.2/CHANGELOG.md +0 -145
- anywidget_vector-0.3.2/src/anywidget_vector/__init__.py +0 -6
- anywidget_vector-0.3.2/src/anywidget_vector/backends/grafeo/__init__.py +0 -20
- anywidget_vector-0.3.2/src/anywidget_vector/backends/grafeo/browser.js +0 -90
- anywidget_vector-0.3.2/src/anywidget_vector/backends/grafeo/client.py +0 -33
- anywidget_vector-0.3.2/src/anywidget_vector/backends/grafeo/converter.py +0 -46
- anywidget_vector-0.3.2/src/anywidget_vector/backends/grafeo/embed.js +0 -95
- anywidget_vector-0.3.2/src/anywidget_vector/ui/__init__.py +0 -340
- anywidget_vector-0.3.2/uv.lock +0 -3122
- {anywidget_vector-0.3.2 → anywidget_vector-0.4.1}/.python-version +0 -0
- {anywidget_vector-0.3.2 → anywidget_vector-0.4.1}/LICENSE +0 -0
- {anywidget_vector-0.3.2 → anywidget_vector-0.4.1}/assets/demo.png +0 -0
- {anywidget_vector-0.3.2 → anywidget_vector-0.4.1}/examples/demo.py +0 -0
- {anywidget_vector-0.3.2 → anywidget_vector-0.4.1}/examples/fashion-mnist-parallel-coords-6d.py +0 -0
- {anywidget_vector-0.3.2 → anywidget_vector-0.4.1}/examples/test_add_numpy.py +0 -0
- {anywidget_vector-0.3.2 → anywidget_vector-0.4.1}/examples/test_projection.py +0 -0
- {anywidget_vector-0.3.2 → anywidget_vector-0.4.1}/src/anywidget_vector/backends/__init__.py +0 -0
- {anywidget_vector-0.3.2 → anywidget_vector-0.4.1}/src/anywidget_vector/backends/chroma/__init__.py +0 -0
- {anywidget_vector-0.3.2 → anywidget_vector-0.4.1}/src/anywidget_vector/backends/chroma/client.py +0 -0
- {anywidget_vector-0.3.2 → anywidget_vector-0.4.1}/src/anywidget_vector/backends/chroma/converter.py +0 -0
- {anywidget_vector-0.3.2 → anywidget_vector-0.4.1}/src/anywidget_vector/backends/lancedb/__init__.py +0 -0
- {anywidget_vector-0.3.2 → anywidget_vector-0.4.1}/src/anywidget_vector/backends/lancedb/client.py +0 -0
- {anywidget_vector-0.3.2 → anywidget_vector-0.4.1}/src/anywidget_vector/backends/lancedb/converter.py +0 -0
- {anywidget_vector-0.3.2 → anywidget_vector-0.4.1}/src/anywidget_vector/backends/pinecone/__init__.py +0 -0
- {anywidget_vector-0.3.2 → anywidget_vector-0.4.1}/src/anywidget_vector/backends/pinecone/converter.py +0 -0
- {anywidget_vector-0.3.2 → anywidget_vector-0.4.1}/src/anywidget_vector/backends/qdrant/__init__.py +0 -0
- {anywidget_vector-0.3.2 → anywidget_vector-0.4.1}/src/anywidget_vector/backends/qdrant/converter.py +0 -0
- {anywidget_vector-0.3.2 → anywidget_vector-0.4.1}/src/anywidget_vector/backends/weaviate/__init__.py +0 -0
- {anywidget_vector-0.3.2 → anywidget_vector-0.4.1}/src/anywidget_vector/backends/weaviate/converter.py +0 -0
- {anywidget_vector-0.3.2 → anywidget_vector-0.4.1}/src/anywidget_vector/py.typed +0 -0
- {anywidget_vector-0.3.2 → anywidget_vector-0.4.1}/tests/__init__.py +0 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main, "release/**", "support/**"]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
# The release workflow runs the full suite before it publishes
|
|
9
|
+
workflow_call:
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
lint:
|
|
13
|
+
name: Lint
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v7
|
|
17
|
+
|
|
18
|
+
- name: Install uv
|
|
19
|
+
uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
|
|
20
|
+
|
|
21
|
+
- name: Check that uv.lock matches pyproject.toml
|
|
22
|
+
run: uv lock --check
|
|
23
|
+
|
|
24
|
+
- name: Run ruff check
|
|
25
|
+
run: uv run --locked --only-group dev ruff check .
|
|
26
|
+
|
|
27
|
+
- name: Run ruff format check
|
|
28
|
+
run: uv run --locked --only-group dev ruff format --check .
|
|
29
|
+
|
|
30
|
+
test:
|
|
31
|
+
name: Test (Python ${{ matrix.python-version }})
|
|
32
|
+
runs-on: ubuntu-latest
|
|
33
|
+
strategy:
|
|
34
|
+
matrix:
|
|
35
|
+
python-version: ["3.12", "3.13", "3.14", "3.15"]
|
|
36
|
+
steps:
|
|
37
|
+
- uses: actions/checkout@v7
|
|
38
|
+
|
|
39
|
+
# Sets UV_PYTHON, so uv uses this version instead of .python-version
|
|
40
|
+
- name: Install uv and Python ${{ matrix.python-version }}
|
|
41
|
+
uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
|
|
42
|
+
with:
|
|
43
|
+
python-version: ${{ matrix.python-version }}
|
|
44
|
+
|
|
45
|
+
# The ESM bundle tests parse and run the widget's JavaScript with Node (the tsc, jsdom and stale-bundle
|
|
46
|
+
# checks need node_modules and skip here: the frontend job runs them once)
|
|
47
|
+
- name: Set up Node.js
|
|
48
|
+
uses: actions/setup-node@v7
|
|
49
|
+
with:
|
|
50
|
+
node-version: "22"
|
|
51
|
+
|
|
52
|
+
- name: Install dependencies
|
|
53
|
+
run: uv sync --locked --extra dev
|
|
54
|
+
|
|
55
|
+
- name: Run tests
|
|
56
|
+
run: uv run --locked --extra dev pytest
|
|
57
|
+
|
|
58
|
+
frontend:
|
|
59
|
+
name: Front end
|
|
60
|
+
runs-on: ubuntu-latest
|
|
61
|
+
steps:
|
|
62
|
+
- uses: actions/checkout@v7
|
|
63
|
+
|
|
64
|
+
- name: Set up Node.js
|
|
65
|
+
uses: actions/setup-node@v7
|
|
66
|
+
with:
|
|
67
|
+
node-version: "22"
|
|
68
|
+
|
|
69
|
+
# esbuild, TypeScript and the type packages, so tsc can check every module in src/ and tests/js/
|
|
70
|
+
- name: Install the front-end dependencies
|
|
71
|
+
run: npm ci --ignore-scripts
|
|
72
|
+
|
|
73
|
+
- name: Install the JavaScript test dependencies
|
|
74
|
+
run: npm ci --ignore-scripts --prefix tests/js
|
|
75
|
+
|
|
76
|
+
- name: Check that the committed bundles are built from the current sources
|
|
77
|
+
run: npm run check
|
|
78
|
+
|
|
79
|
+
- name: Type-check the front end
|
|
80
|
+
run: npm run typecheck
|
|
81
|
+
|
|
82
|
+
- name: Run the JavaScript tests
|
|
83
|
+
run: npm test
|
|
84
|
+
|
|
85
|
+
build:
|
|
86
|
+
name: Build
|
|
87
|
+
runs-on: ubuntu-latest
|
|
88
|
+
steps:
|
|
89
|
+
- uses: actions/checkout@v7
|
|
90
|
+
|
|
91
|
+
- name: Install uv
|
|
92
|
+
uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
|
|
93
|
+
|
|
94
|
+
- name: Build package
|
|
95
|
+
run: uv build
|
|
96
|
+
|
|
97
|
+
- name: Check package
|
|
98
|
+
run: uvx twine check dist/*
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
name: Grafeo Latest
|
|
2
|
+
|
|
3
|
+
# Early warning for engine changes: runs the suite against the newest grafeo on
|
|
4
|
+
# PyPI (pre-releases included, even outside the pinned range) and the browser
|
|
5
|
+
# backend against the pinned and the newest @grafeo-db/wasm on npm.
|
|
6
|
+
|
|
7
|
+
on:
|
|
8
|
+
schedule:
|
|
9
|
+
- cron: "0 6 * * 1" # Mondays 06:00 UTC
|
|
10
|
+
workflow_dispatch:
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
python:
|
|
14
|
+
name: Test with newest grafeo (Python ${{ matrix.python-version }})
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
strategy:
|
|
17
|
+
fail-fast: false
|
|
18
|
+
matrix:
|
|
19
|
+
python-version: ["3.12", "3.13", "3.14", "3.15"]
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@v7
|
|
22
|
+
|
|
23
|
+
- name: Install uv and Python ${{ matrix.python-version }}
|
|
24
|
+
uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
|
|
25
|
+
with:
|
|
26
|
+
python-version: ${{ matrix.python-version }}
|
|
27
|
+
|
|
28
|
+
- name: Install dependencies
|
|
29
|
+
run: |
|
|
30
|
+
uv sync --extra dev
|
|
31
|
+
uv pip install --upgrade --prerelease allow grafeo
|
|
32
|
+
|
|
33
|
+
- name: Show grafeo build
|
|
34
|
+
run: uv run --no-sync python -c "import grafeo; print(grafeo.__version__); print(grafeo.build_info())"
|
|
35
|
+
|
|
36
|
+
- name: Run tests
|
|
37
|
+
run: uv run --no-sync pytest
|
|
38
|
+
|
|
39
|
+
wasm:
|
|
40
|
+
name: WASM smoke test (${{ matrix.release }} @grafeo-db/wasm)
|
|
41
|
+
runs-on: ubuntu-latest
|
|
42
|
+
strategy:
|
|
43
|
+
fail-fast: false
|
|
44
|
+
matrix:
|
|
45
|
+
release: [pinned, newest]
|
|
46
|
+
steps:
|
|
47
|
+
- uses: actions/checkout@v7
|
|
48
|
+
|
|
49
|
+
- name: Set up Node.js
|
|
50
|
+
uses: actions/setup-node@v7
|
|
51
|
+
with:
|
|
52
|
+
node-version: "22"
|
|
53
|
+
|
|
54
|
+
- name: Resolve version
|
|
55
|
+
id: version
|
|
56
|
+
run: |
|
|
57
|
+
if [ "${{ matrix.release }}" = "pinned" ]; then
|
|
58
|
+
version=$(sed -n 's/^export const GRAFEO_WASM_VERSION = "\(.*\)";$/\1/p' src/anywidget_vector/backends/grafeo/embed.ts)
|
|
59
|
+
else
|
|
60
|
+
version=$(npm view @grafeo-db/wasm versions --json | node -e 'const v = JSON.parse(require("fs").readFileSync(0, "utf8")); console.log([].concat(v).pop())')
|
|
61
|
+
fi
|
|
62
|
+
echo "version=$version" >> "$GITHUB_OUTPUT"
|
|
63
|
+
|
|
64
|
+
- name: Download @grafeo-db/wasm@${{ steps.version.outputs.version }}
|
|
65
|
+
run: |
|
|
66
|
+
mkdir -p "$RUNNER_TEMP/wasm"
|
|
67
|
+
cd "$RUNNER_TEMP/wasm"
|
|
68
|
+
npm pack "@grafeo-db/wasm@${{ steps.version.outputs.version }}"
|
|
69
|
+
tar -xzf grafeo-db-wasm-*.tgz
|
|
70
|
+
|
|
71
|
+
- name: Run smoke test
|
|
72
|
+
run: node tests/js/wasm_smoke.ts "$RUNNER_TEMP/wasm/package"
|
|
@@ -15,25 +15,34 @@ on:
|
|
|
15
15
|
- pypi
|
|
16
16
|
|
|
17
17
|
jobs:
|
|
18
|
+
test:
|
|
19
|
+
name: Test
|
|
20
|
+
uses: ./.github/workflows/ci.yml
|
|
21
|
+
|
|
18
22
|
build:
|
|
19
23
|
name: Build distribution
|
|
24
|
+
needs: test
|
|
20
25
|
runs-on: ubuntu-latest
|
|
21
26
|
steps:
|
|
22
|
-
- uses: actions/checkout@
|
|
27
|
+
- uses: actions/checkout@v7
|
|
23
28
|
|
|
24
|
-
- name:
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
29
|
+
- name: Check the release tag matches the package version
|
|
30
|
+
if: github.event_name == 'release'
|
|
31
|
+
run: |
|
|
32
|
+
version=$(python3 -c "import tomllib; print(tomllib.load(open('pyproject.toml', 'rb'))['project']['version'])")
|
|
33
|
+
if [ "$GITHUB_REF_NAME" != "v$version" ]; then
|
|
34
|
+
echo "Release tag $GITHUB_REF_NAME does not match the package version $version"
|
|
35
|
+
exit 1
|
|
36
|
+
fi
|
|
28
37
|
|
|
29
|
-
- name: Install
|
|
30
|
-
|
|
38
|
+
- name: Install uv
|
|
39
|
+
uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
|
|
31
40
|
|
|
32
41
|
- name: Build package
|
|
33
|
-
run:
|
|
42
|
+
run: uv build
|
|
34
43
|
|
|
35
44
|
- name: Upload distribution artifacts
|
|
36
|
-
uses: actions/upload-artifact@
|
|
45
|
+
uses: actions/upload-artifact@v7
|
|
37
46
|
with:
|
|
38
47
|
name: dist
|
|
39
48
|
path: dist/
|
|
@@ -48,7 +57,7 @@ jobs:
|
|
|
48
57
|
id-token: write
|
|
49
58
|
steps:
|
|
50
59
|
- name: Download distribution artifacts
|
|
51
|
-
uses: actions/download-artifact@
|
|
60
|
+
uses: actions/download-artifact@v8
|
|
52
61
|
with:
|
|
53
62
|
name: dist
|
|
54
63
|
path: dist/
|
|
@@ -68,7 +77,7 @@ jobs:
|
|
|
68
77
|
id-token: write
|
|
69
78
|
steps:
|
|
70
79
|
- name: Download distribution artifacts
|
|
71
|
-
uses: actions/download-artifact@
|
|
80
|
+
uses: actions/download-artifact@v8
|
|
72
81
|
with:
|
|
73
82
|
name: dist
|
|
74
83
|
path: dist/
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [0.4.1] - 2026-11-12
|
|
4
|
+
|
|
5
|
+
Grafeo 0.6.2 release: the Grafeo backend moves to grafeo 0.6.2 in Python and in the browser, and the front end is TypeScript, bundled by esbuild. An environment with the `grafeo` extra upgrades grafeo to 0.6.2 or later; to keep grafeo 0.6.0 or 0.6.1, stay on anywidget-vector 0.4.0 and pin grafeo.
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- **Front end in TypeScript**: The widget loads `ui/dist/widget.js`, built by esbuild from the modules in `ui/` and `backends/` (`npm run build`), instead of the JavaScript modules joined as text. `to_html()` uses its own bundle, `ui/dist/export.js`, with the page template in `ui/export.html`.
|
|
10
|
+
- **Release checks**: CI type-checks the front end with `tsc` (`npm run typecheck`), runs the JavaScript tests (`npm test`), and fails when a committed bundle is stale.
|
|
11
|
+
- **grafeo-server version**: The README says the `server` Grafeo mode needs grafeo-server 0.6.0 or later, the Grafeo 0.6 engine, which sends decimals as `{"$decimal": "..."}` (the widget turns them into numbers).
|
|
12
|
+
- **Exported pages draw points in one call**: `to_html()` and `save_html()` draw every point as an instance of one mesh instead of one mesh per point.
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
|
|
16
|
+
- **Exported point sizes match the widget**: `to_html()` scales `size_range` by the data extent, as the live view does.
|
|
17
|
+
- **An exported single point is in view**: A page with one point, or with points that share a position, places the camera away from them instead of on them.
|
|
18
|
+
- **The exported tooltip hides on leave**: Moving the pointer off an exported page hides the tooltip.
|
|
19
|
+
- **Pinecone fetches by id show their points**: A `{"ids": [...]}` query reads the fetched records (previously it showed no points), sends the configured `namespace`, and encodes each id, so ids with `&` or `#` resolve.
|
|
20
|
+
- **WASM mode creates one database**: Queries started while `@grafeo-db/wasm` loads share one database instead of each creating one.
|
|
21
|
+
- **The Run button shows Python-side queries**: For backends that run in Python (Grafeo embedded, Chroma, LanceDB), the button stays in its loading state until the result arrives.
|
|
22
|
+
- **A widget without WebGL leaves no listeners**: When the 3D canvas cannot be created, the view removes the model and theme listeners it had added.
|
|
23
|
+
- **Neighbor names fall back to the id**: The sidebar's distance list shows the id for a point whose `label` is empty.
|
|
24
|
+
|
|
25
|
+
### Dependencies
|
|
26
|
+
|
|
27
|
+
- **grafeo 0.6.2** (requires `>=0.6.2,<0.7`): The `grafeo` and `dev` extras need grafeo 0.6.2, and the `wasm` mode loads `@grafeo-db/wasm` 0.6.2 (`GRAFEO_WASM_VERSION` in `backends/grafeo/embed.ts`).
|
|
28
|
+
- **Locked versions refreshed**: 35 packages, among them ty 0.0.100, typer 0.29.0, pandas 3.1.1, lancedb 0.41.0, ruff 0.17.4 and python-dateutil 4.0.0. Front-end build tools: esbuild 0.28.2, TypeScript 7.0.2 and `@types/three` 0.186.0.
|
|
29
|
+
|
|
30
|
+
## [0.4.0] - 2026-10-28
|
|
31
|
+
|
|
32
|
+
Requires Python 3.12 or later; the Grafeo backend requires grafeo 0.6. See "Upgrading to 0.4" in the README.
|
|
33
|
+
|
|
34
|
+
### Breaking
|
|
35
|
+
|
|
36
|
+
- **Grafeo 0.6**: The `grafeo` extra requires `grafeo>=0.6.0,<0.7`; grafeo 0.5.x is no longer supported. Grafeo 0.6 changes query results and files, and these reach the widget's Grafeo backend:
|
|
37
|
+
- Every database is a single file. The first read-write open of a 0.5.x database migrates it and keeps the old file as `<file>.pre-0.6`, which 0.5.x needs to go back; opening a directory that is not a 0.5.x database fails
|
|
38
|
+
- A GQL number with a point is an exact decimal, so `0.0/0.0` and `1/0` fail the query (division by zero) where they gave NaN or null, and so does integer overflow. Use exponent literals (`0.0e0/0.0e0`) for IEEE floats
|
|
39
|
+
- A `WHERE` right after `INSERT`, `CREATE`, `MERGE` or `DELETE` is an error, and an `INSERT` alone returns no rows, so running one from the toolbar clears the scene
|
|
40
|
+
- GQL `ORDER BY` puts nulls last in both directions
|
|
41
|
+
- **Theme follows the page until you choose**: `dark_mode` reports the theme in use. The widget follows the host page until a theme is chosen (`VectorSpace(dark_mode=...)`, `widget.dark_mode = ...` before or after display, even to the value it already reports, or the settings toggle) and then keeps the choice, also in later views; before, the page theme overwrote `dark_mode` passed from Python, and the widget stopped following the page after its first automatic change. The canvas `background` follows the theme unless chosen the same way; before, the theme overwrote it. Same contract as anywidget-graph and anywidget-archimate (`_theme_explicit`, `_background_explicit`)
|
|
42
|
+
- **Compact toolbar in a narrow widget**: The toolbar tightens when the widget itself is narrower than 600 px (a container query), not only when the window is narrow, as in anywidget-graph. Panels over the canvas (window narrower than 768 px) now cover the canvas's zoom and selection controls instead of sitting under them
|
|
43
|
+
- **WASM engine 0.6**: The browser-side Grafeo backend loads `@grafeo-db/wasm` 0.6.0 (was 0.5.0 in 0.3.2) from jsDelivr. The version is set once, `GRAFEO_WASM_VERSION` in `backends/grafeo/embed.js`, and a test keeps it in lockstep with the Python pin (npm and PyPI spellings of a pre-release, such as `0.6.1-rc.2` and `0.6.1rc2`, compare as the same version)
|
|
44
|
+
|
|
45
|
+
### Improvements
|
|
46
|
+
|
|
47
|
+
- **Decimals become numbers**: Grafeo 0.6 returns decimals (`decimal.Decimal` in Python, `{"$decimal": "1.50"}` in WASM). The widget turns them into floats in every Grafeo mode, also inside lists, maps and node properties, so `RETURN 0.5 AS score` maps to color and size, `1.5 AS x` places a point, and a plain list `[1.0, 0.0, 0.0]` still gives a vector. Without this, Python points could not be sent to the browser as JSON and WASM points landed at the origin
|
|
48
|
+
- **Vector search errors**: A query vector of the wrong size or with NaN is a regular `grafeo.GrafeoError` in Grafeo 0.6 (0.5.44 panicked, and its WASM build trapped), shown in the widget with the sizes it names. The panic guard stays for any other engine bug
|
|
49
|
+
- **Three.js 0.186.1, bundled**: The widget and `to_html()` use Three.js 0.186.1 (was 0.160.0 from esm.sh), bundled with the package (`ui/vendor/three.min.js` with its license, built by `scripts/vendor`), so both work offline and under a strict Content Security Policy. Only the `wasm` Grafeo mode loads code from a CDN. Three.js dropped WebGL 1 in 0.163, so a browser needs WebGL 2
|
|
50
|
+
- **Theme detection**: A `data-theme="dark"` or `"light"` on the widget's closest ancestor wins, then on `<html>` and `<body>`, then a `dark` or `light` class, then the operating system. `data-theme="light"` no longer loses to a dark operating system, and other `data-theme` values (design-system names) are ignored
|
|
51
|
+
- **Release safety**: The PyPI workflow runs the full CI suite first and stops when the release tag is not `v` plus the `pyproject.toml` version. CI also runs on `release/**` and `support/**` branches
|
|
52
|
+
- **Credentials documented**: The README says where backend credentials end up (the browser and saved notebook widget state) and how to limit that
|
|
53
|
+
- **Dependencies**: Requires anywidget 0.11 or later (was 0.9.21). The `chroma` and `all` extras pin `chromadb==1.5.8`, because 1.5.9 has security issues. All locked dependencies refreshed (`uv lock --upgrade`), and the dev tools need current releases (pytest 9.2, ruff 0.17.3, ty 0.0.94, prek 0.5.7, marimo 0.25.2); the `dev` extra includes grafeo, numpy and packaging so the full test suite runs everywhere. CI and the release workflow use uv (`uv lock --check`, `uv sync --locked`, `uv build`) and current GitHub Actions (checkout v7, setup-uv v10.3.3 pinned by commit since setup-uv publishes no moving major tag, setup-node v7, upload-artifact v7, download-artifact v8). The `tool.uv.dev-dependencies` table moved to `[dependency-groups]`, and ruff leaves Markdown files alone
|
|
54
|
+
- **Engine contract tests**: The tests that pin Grafeo behavior now cover 0.6: error classes and messages for unknown metrics, zero dimensions, wrong-size and NaN query vectors and NaN in an indexed vector, filter operators (`$in`, `$ne`), tied distances, decimal literals and an `INSERT` without rows. `tests/js/wasm_smoke.mjs` checks decimals and the wrong-size error in WASM
|
|
55
|
+
- **Same points in every Grafeo mode**: Embedded, server and WASM results go through the same rules: node values (`RETURN n`) contribute their properties, labels and id, unaliased columns such as `n.embedding` or `id(n)` are recognized, and explicit `x`/`y`/`z` win over the first vector components
|
|
56
|
+
- **Server errors**: grafeo-server error responses show their `detail` text instead of raw JSON
|
|
57
|
+
- **Scheduled engine check**: A weekly workflow runs the suite against the newest grafeo on PyPI (pre-releases included) and a smoke test against the pinned and the newest `@grafeo-db/wasm`
|
|
58
|
+
- **Python 3.15**: Tested on Python 3.15; CI runs the suite on 3.12 to 3.15 and the classifiers list 3.12 to 3.15
|
|
59
|
+
|
|
60
|
+
### Bug Fixes
|
|
61
|
+
|
|
62
|
+
- **Embedded Grafeo queries**: Queries failed with "'QueryBuilder' object is not iterable" because the client called `GrafeoDB.query()`, which returns a query builder. It now calls `execute()`
|
|
63
|
+
- **WASM mode**: `@grafeo-db/wasm` is published for bundlers since 0.5.x, so importing it from esm.sh no longer yields a working `Database`. The loader now imports the JS glue and instantiates the binary itself. WASM vectors (`Float32Array`) are converted to arrays, so they place points and sync to Python
|
|
64
|
+
- **Engine panics**: A Grafeo panic (for example a vector search with the wrong number of dimensions) escaped the query callback because pyo3 raises it as a `BaseException`. It is now reported as a query error
|
|
65
|
+
- **Query status**: A Python-side query with an empty result left the status at "connecting" and kept the old points. The result now replaces the points and the status becomes "connected"; a new query clears the previous error
|
|
66
|
+
- **NaN and infinity in points**: These values are not valid JSON and one NaN coordinate broke camera framing for the whole scene. Top-level non-finite values are now replaced with `None` (with a `RuntimeWarning`), and distance and focus methods treat `None` coordinates as 0
|
|
67
|
+
- **HTML injection**: Point labels and values from a database were inserted as HTML in the tooltip, the properties panel and the exported HTML page. They are now set as text. `to_html()` also escapes the title and keeps a `</script>` inside the data from ending the script
|
|
68
|
+
- **Vector edge cases**: `add_numpy()` with a single high-dimensional row, a 1-D or one-column array, or ids/labels/metadata of the wrong length raised an unrelated `IndexError`; it now works (single row) or raises a clear `ValueError`. `project()` handles a single point and reports ragged or non-finite vectors clearly. `compute_distances(vector_field=...)` leaves out points without that vector instead of returning infinity, and raises on vectors of different lengths instead of truncating them
|
|
69
|
+
- **Version**: `anywidget_vector.__version__` reported 0.2.5; it now reads the installed package version
|
|
70
|
+
- **Removed views kept running**: A removed or re-rendered widget kept its model listeners, its theme observers and its dark-mode media listener, so old views went on updating `dark_mode` and `background`. Removing a view now detaches all of them
|
|
71
|
+
- **WASM engine loaded twice**: Two copies of the widget module on one page (a cell run again, a marimo reconnect, anywidget-graph next to it) each instantiated the cached `@grafeo-db/wasm` glue, which broke the databases of the first copy. The loading promise now lives on `globalThis`, keyed by the glue URL
|
|
72
|
+
- **Stale query results**: A slower, older browser-side query could overwrite the result of a newer one. Only the newest query per widget now sets points, errors and the loading state
|
|
73
|
+
- **HTML export sizes**: `to_html(width=..., height=...)` placed the values in the page's `<style>` unchecked; a value that is not a plain CSS size now raises `ValueError`
|
|
74
|
+
- **Source distribution**: A local `uv build` packed the `.claude/` folder (agent notes and local settings) into the sdist; it is now excluded
|
|
75
|
+
|
|
76
|
+
## [0.3.2] - 2026-03-16
|
|
77
|
+
|
|
78
|
+
### Improvements
|
|
79
|
+
|
|
80
|
+
- **Marimo reactivity fix**: Removed camera and hover JS-to-Python sync to prevent continuous cell re-execution. Only user-initiated actions (selection, mode change) now trigger marimo reactive updates
|
|
81
|
+
- **Custom scroll zoom**: Replaced OrbitControls zoom with a custom wheel handler for much finer granularity
|
|
82
|
+
- **Selection hides completely**: Lasso/box selection now fully hides non-selected points (scale-to-zero for instanced meshes) instead of dimming
|
|
83
|
+
- **Auto zoom-to-fit on selection**: Camera automatically frames the selected points after lasso/box selection
|
|
84
|
+
- **Search filter modes**: Typing in the search bar dims non-matching points as a preview, pressing Run/Enter hides them completely
|
|
85
|
+
- **Hover via callback**: Properties panel hover now uses a direct JS callback instead of model sync, eliminating unnecessary Python round-trips
|
|
86
|
+
|
|
87
|
+
### Bug Fixes
|
|
88
|
+
|
|
89
|
+
- **setSelection scoping**: Moved `setSelection` helper to `createCanvas` scope so lasso/box/click handlers can access it
|
|
90
|
+
- **Camera debounce variable**: Fixed `_cameraDebounce` lexical declaration error by moving it to the correct scope
|
|
91
|
+
|
|
92
|
+
## [0.3.1] - 2026-03-16
|
|
93
|
+
|
|
94
|
+
### New Features
|
|
95
|
+
|
|
96
|
+
- **Lasso selection**: New lasso mode for freehand point selection in the 3D canvas, with point-in-polygon hit testing
|
|
97
|
+
- **Selection highlighting**: Selected points show wireframe highlight rings and non-selected points are dimmed to 15% brightness
|
|
98
|
+
- **Auto-sizing**: Width defaults to 100% (fill container), height defaults to 1:1 aspect ratio. Both can still be set to fixed pixel values
|
|
99
|
+
|
|
100
|
+
### Bug Fixes
|
|
101
|
+
|
|
102
|
+
- **Properties panel**: Panel is now always created (previously skipped when `show_properties=False`), so the toolbar button always works. Starts closed unless `show_properties=True`
|
|
103
|
+
- **Distance metric feedback**: Changing the metric now auto-enables k=5 connections when a point is selected, giving immediate visual feedback
|
|
104
|
+
|
|
105
|
+
### Improvements
|
|
106
|
+
|
|
107
|
+
- Reduced scroll zoom sensitivity (`zoomSpeed` halved to 0.5)
|
|
108
|
+
- Search filter dimming increased from 12% to 6% opacity for clearer visual contrast
|
|
109
|
+
- Camera no longer resets on every point update (only on initial load)
|
|
110
|
+
- Cross-widget filtering: example updated so VectorSpace lasso selection feeds back into ParallelCoordinates dimming via marimo reactivity
|
|
111
|
+
|
|
112
|
+
## [0.3.0] - 2026-03-16
|
|
113
|
+
|
|
114
|
+
### New Features
|
|
115
|
+
|
|
116
|
+
- **Distance metrics sidebar**: Distance section with metric selector (euclidean, cosine, manhattan, dot product), configurable k-neighbors (0-50) and live nearest-neighbor display for the selected point
|
|
117
|
+
- **Dimension mapping display**: Sidebar now shows active visual mapping fields: color field, size range, shape field and unique shape count
|
|
118
|
+
|
|
119
|
+
### Improvements
|
|
120
|
+
|
|
121
|
+
- Improved sidebar styling and layout
|
|
122
|
+
|
|
123
|
+
## [0.2.8] - 2026-03-15
|
|
124
|
+
|
|
125
|
+
### New Features
|
|
126
|
+
|
|
127
|
+
- **6D parallel coordinates example**: Fashion-MNIST demo with PCA across 6+ dimensions, interactive axis mapping and shape mapping to categorical labels
|
|
128
|
+
|
|
129
|
+
## [0.2.7] - 2026-03-15
|
|
130
|
+
|
|
131
|
+
### New Features
|
|
132
|
+
|
|
133
|
+
- **Dark/light mode toggle**: `dark_mode` trait with real-time CSS color scheme switching and theme-aware styling across all panels
|
|
134
|
+
|
|
135
|
+
## [0.2.6] - 2026-03-15
|
|
136
|
+
|
|
137
|
+
### New Features
|
|
138
|
+
|
|
139
|
+
- **NumPy array support**: `add_numpy()` method for adding points from arrays with automatic PCA projection for high-dimensional data (D > 3)
|
|
140
|
+
- **Dimensionality reduction**: `project()` method with PCA, t-SNE and UMAP support; `set_vectors()` for storing high-dimensional vectors separately
|
|
141
|
+
- **Example scripts**: Projection demo and numpy integration examples
|
|
142
|
+
|
|
143
|
+
### Improvements
|
|
144
|
+
|
|
145
|
+
- High-dimensional vector storage without syncing to JavaScript
|
|
146
|
+
- Coordinate normalization after projection
|
|
147
|
+
- Added demo screenshot to README
|
|
148
|
+
|
|
149
|
+
## [0.2.5] - 2026-03-04
|
|
150
|
+
|
|
151
|
+
### Bug Fixes
|
|
152
|
+
|
|
153
|
+
- Fixed lasso selection stability issues
|
|
154
|
+
- Removed problematic custom traitlets implementation
|
|
155
|
+
|
|
156
|
+
### Improvements
|
|
157
|
+
|
|
158
|
+
- Added keyboard shortcuts: F to fit view, Escape to clear selection
|
|
159
|
+
- Better visual feedback for selection modes
|
|
160
|
+
- Cleaner toolbar layout with integrated mode controls
|
|
161
|
+
|
|
162
|
+
## [0.2.4] - 2026-03-02
|
|
163
|
+
|
|
164
|
+
### New Features
|
|
165
|
+
|
|
166
|
+
- **Zoom and pan controls**: Zoom in, zoom out and fit-to-view buttons in the toolbar
|
|
167
|
+
- **Box selection mode**: New selection mode alongside click and multi-select, with visual feedback during selection
|
|
168
|
+
- **HTML export**: `to_html()` and `save_html()` methods for self-contained HTML output with embedded data and Three.js
|
|
169
|
+
|
|
170
|
+
### Improvements
|
|
171
|
+
|
|
172
|
+
- Improved camera fitting algorithm for better initial view framing
|
|
173
|
+
- Updated README with comprehensive usage examples
|
|
174
|
+
- Updated dependencies
|
|
175
|
+
|
|
176
|
+
## [0.2.3] - 2026-02-12
|
|
177
|
+
|
|
178
|
+
### New Features
|
|
179
|
+
|
|
180
|
+
- **Sidebar explorer**: Three collapsible sections: collections browser, dimensions explorer (point count, dimensionality, axis ranges) and clusters explorer (grouped by color field with sizes)
|
|
181
|
+
- **Browser-side Grafeo backend**: JavaScript client for Grafeo server and WASM-embedded queries
|
|
182
|
+
- **Demo module**: Reference implementation showing various widget features
|
|
183
|
+
|
|
184
|
+
### Improvements
|
|
185
|
+
|
|
186
|
+
- Consistency pass across all backend modules
|
|
187
|
+
- Ruff configuration tuned for marimo compatibility
|
|
188
|
+
|
|
189
|
+
## [0.2.2] - 2026-02-07
|
|
190
|
+
|
|
191
|
+
### New Features
|
|
192
|
+
|
|
193
|
+
- **Streaming factory methods**: `from_numpy()`, `from_umap()` and `from_arrays()` constructors for various data formats
|
|
194
|
+
|
|
195
|
+
### Improvements
|
|
196
|
+
|
|
197
|
+
- Added Apache 2.0 license
|
|
198
|
+
- Expanded test suite with 194 additional test cases
|
|
199
|
+
- ESM bundle aggregation for widget JavaScript
|
|
200
|
+
|
|
201
|
+
## [0.2.1] - 2026-02-03
|
|
202
|
+
|
|
203
|
+
### New Features
|
|
204
|
+
|
|
205
|
+
- **Multi-backend architecture**: Six backends: Qdrant, Pinecone, Weaviate (browser-side REST), Chroma, LanceDB, Grafeo (Python-side)
|
|
206
|
+
- **Modular UI**: Separated rendering into canvas, settings, properties and toolbar components
|
|
207
|
+
- **Backend factory methods**: `from_qdrant()`, `from_pinecone()`, `from_weaviate()`, `from_chroma()`, `from_lancedb()`, `from_grafeo()`
|
|
208
|
+
- **Event system**: `on_click()`, `on_hover()` and `on_selection()` decorators with callback signatures
|
|
209
|
+
- **CI/CD**: GitHub Actions pipelines for testing and PyPI publishing
|
|
210
|
+
|
|
211
|
+
### Improvements
|
|
212
|
+
|
|
213
|
+
- Refactored monolithic widget into modular component architecture
|
|
214
|
+
- Added README with usage examples
|
|
215
|
+
|
|
216
|
+
## [0.1.0] - 2026-02-03
|
|
217
|
+
|
|
218
|
+
- Initial release: Three.js-based interactive 3D vector visualization with instanced rendering, six shape types, continuous and categorical color mapping, orbit controls, hover tooltips, axes/grid display and raycast-based selection
|