`partgroup` is null on 93k rows of `gs.osm_skinny` and empty on another 111k, and the pivot showed those groups with no `+`: no way to drill into them at all, while every named sibling opened. The cause is upstream, in the datagrid's `cell_style_row_header`. A tree row's header is the label cell padded on its left by one blank cell per level above it, and it told padding from label by testing the cell's own text — so a node whose group key is blank read as padding, got no `psp-tree-label`, and therefore no caret. The click handler gates on the same class, so the cell was not clickable either. The node was in the traversal and its children existed; only the affordance was missing. Tell them apart structurally instead: the label is the last defined entry in `row_header`, which is how `is_collapse` two lines below already reads the following row. Flat rollup has no padding to distinguish and keeps the text test. Rebuilt the vendored packages from fork branch `expand-blank-tree-nodes`, which stacks this on the depth patch already carried. Note that `npm install` on its own will not pick a rebuilt tarball up — the version in the filename never changes and the lock pins an integrity hash, so npm serves the old one from its cache and nothing reports a problem. The README and the rebuild script now say to re-resolve by path. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
133 lines
6.2 KiB
Bash
Executable File
133 lines
6.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# rebuild-perspective.sh — rebuild the patched Perspective and re-vendor it
|
|
#
|
|
# pf_app runs a patched build of Perspective that exposes the column axis
|
|
# expand/collapse the engine already implements (split_by_depth, and
|
|
# expand_column/collapse_column). Upstream does not ship this yet, so the
|
|
# built packages are vendored into this directory as npm tarballs.
|
|
#
|
|
# Source of truth: https://github.com/fleetside72/perspective
|
|
# branch expand-blank-tree-nodes (tip of the patch stack)
|
|
#
|
|
# This script exists because vendored binaries are opaque: once the .tgz files
|
|
# are committed, nothing in the repo records how to regenerate them. Run this
|
|
# after changing the fork, then commit the resulting tarballs.
|
|
#
|
|
# Only needed on a machine that is changing the engine. Deploys just run
|
|
# `npm install`, which expands the committed tarballs - see ../README in this
|
|
# directory.
|
|
# ---------------------------------------------------------------------------
|
|
|
|
PSP="${PSP_DIR:-$HOME/perspective}"
|
|
BRANCH="${PSP_BRANCH:-expand-blank-tree-nodes}"
|
|
VENDOR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
|
|
# The four packages that must move together. Perspective's own docs are
|
|
# emphatic that loader, packages, data format and apache-arrow are one unit;
|
|
# vendoring a subset would reintroduce exactly the drift that causes trouble.
|
|
PACKAGES=(
|
|
"rust/perspective-js"
|
|
"rust/perspective-server"
|
|
"rust/perspective-viewer"
|
|
"packages/viewer-datagrid"
|
|
)
|
|
|
|
info() { echo -e "\033[0;34m==>\033[0m $*"; }
|
|
ok() { echo -e "\033[0;32m ✓\033[0m $*"; }
|
|
die() { echo -e "\033[0;31m ✗\033[0m $*" >&2; exit 1; }
|
|
|
|
# -- preflight --------------------------------------------------------------
|
|
[[ -d "$PSP" ]] || die "No Perspective checkout at $PSP.
|
|
git clone https://github.com/fleetside72/perspective.git $PSP
|
|
cd $PSP && git checkout $BRANCH
|
|
Set PSP_DIR to use a different path."
|
|
|
|
command -v pnpm >/dev/null || die "pnpm not found. Perspective builds with pnpm, not npm."
|
|
|
|
# The repo pins its Rust toolchain, emsdk and Binaryen exactly, but pins nothing
|
|
# for the host tools -- no packageManager, no .nvmrc -- so `npm i -g pnpm` gets
|
|
# whatever is newest and that is not what this tree was written against. pnpm 11+
|
|
# rejects a repeated `--if-present`, which sh_perspective.mjs emits once per
|
|
# package in scope, and the build dies with:
|
|
# error: the argument '--if-present' cannot be used multiple times
|
|
pnpm_major=$(pnpm --version | cut -d. -f1)
|
|
if (( pnpm_major > 10 )); then
|
|
die "pnpm $(pnpm --version) is too new; this tree needs pnpm 10.x.
|
|
npm i -g pnpm@10"
|
|
fi
|
|
command -v protoc >/dev/null || die "protoc not found.
|
|
Its VERSION selects which protobuf source tree the build clones, and a
|
|
version below 22 pulls a layout the build cannot consume. Needs >= 22
|
|
(33.2 known good). Distro packages are usually far too old."
|
|
|
|
cmake_ver=$(cmake --version 2>/dev/null | head -1 | grep -oE '[0-9]+\.[0-9]+(\.[0-9]+)?') || die "cmake not found"
|
|
cmake_major=${cmake_ver%%.*}; cmake_minor=$(echo "$cmake_ver" | cut -d. -f2)
|
|
if (( cmake_major < 3 || (cmake_major == 3 && cmake_minor < 29) )); then
|
|
die "cmake $cmake_ver is too old; Perspective needs >= 3.29.5.
|
|
A user-level install works: pip3 install --user 'cmake==3.31.*'"
|
|
fi
|
|
# And not too new: CMake 4 dropped compatibility with cmake_minimum_required
|
|
# below 3.5, which Perspective's C++ dependencies still declare. `pip install
|
|
# cmake` gives 4.x by default, which satisfies the floor above and then fails
|
|
# in the middle of the Arrow build.
|
|
if (( cmake_major >= 4 )); then
|
|
die "cmake $cmake_ver is too new; CMake 4 removed support for
|
|
cmake_minimum_required < 3.5, which the C++ dependencies still use.
|
|
pip3 install --user 'cmake==3.31.*'"
|
|
fi
|
|
|
|
info "Perspective checkout: $PSP"
|
|
git -C "$PSP" rev-parse --abbrev-ref HEAD | grep -qx "$BRANCH" \
|
|
|| echo " ! on branch $(git -C "$PSP" rev-parse --abbrev-ref HEAD), expected $BRANCH"
|
|
commit=$(git -C "$PSP" rev-parse --short HEAD)
|
|
dirty=$(git -C "$PSP" status --porcelain | wc -l)
|
|
echo " commit $commit$([[ $dirty -gt 0 ]] && echo " (+$dirty uncommitted files)")"
|
|
|
|
# -- build ------------------------------------------------------------------
|
|
# `metadata` first: it generates docs/expression_gen.md, which perspective-client
|
|
# includes at compile time. Building a scope without it fails on the missing file.
|
|
info "Building (this takes ~40 minutes cold, a few minutes warm)…"
|
|
( cd "$PSP" && PSP_ONCE=1 PACKAGE="metadata,server,client,viewer,viewer-datagrid" pnpm run build )
|
|
ok "build complete"
|
|
|
|
# -- pack -------------------------------------------------------------------
|
|
# pnpm pack, not npm pack. These packages depend on each other as
|
|
# `workspace:^`, and only pnpm rewrites that to the concrete version on pack.
|
|
# npm leaves it, and npm install then refuses the tarball outright:
|
|
# npm error Unsupported URL Type "workspace:": workspace:^
|
|
info "Packing tarballs into $VENDOR"
|
|
rm -f "$VENDOR"/*.tgz
|
|
for p in "${PACKAGES[@]}"; do
|
|
( cd "$PSP/$p" && pnpm pack --pack-destination "$VENDOR" >/dev/null )
|
|
ok "$(basename "$p")"
|
|
done
|
|
|
|
# -- record provenance ------------------------------------------------------
|
|
# A committed .tgz is an opaque binary; without this the tie back to source is
|
|
# only in someone's memory.
|
|
cat > "$VENDOR/PROVENANCE.txt" <<EOF
|
|
Built from https://github.com/fleetside72/perspective
|
|
branch $BRANCH
|
|
commit $(git -C "$PSP" rev-parse HEAD)
|
|
based on $(git -C "$PSP" describe --tags --abbrev=0 2>/dev/null || echo 'unknown')
|
|
built $(date -u +%Y-%m-%dT%H:%M:%SZ) on $(hostname)
|
|
dirty $dirty uncommitted file(s) in the source tree at build time
|
|
|
|
Regenerate with ui/vendor/rebuild-perspective.sh
|
|
EOF
|
|
|
|
echo
|
|
ls -la "$VENDOR"/*.tgz | awk '{printf " %-52s %5.1f MB\n", $NF, $5/1048576}'
|
|
echo
|
|
ok "Done. Now, from ui/ — note the paths: npm resolves these from its cache
|
|
otherwise, since the version in the filename never changes.
|
|
|
|
rm -rf node_modules/@perspective-dev
|
|
npm install ./vendor/perspective-dev-{client,server,viewer,viewer-datagrid}-5.4.0.tgz
|
|
git add vendor package-lock.json && git commit"
|
|
[[ $dirty -gt 0 ]] && echo -e "\033[1;33m !\033[0m source tree had uncommitted changes — push them to the fork first"
|
|
exit 0
|