ViewConfig::apply_update in perspective-client applies ten fields and
neither group_by_depth nor split_by_depth is among them. A depth therefore
works when a view is created -- table.view({ group_by_depth: 1 }), which is
what the fork's own depth_test.mjs exercises -- and is silently discarded by
restore(), which is how a viewer changes its own configuration. That is why
the EXPAND buttons did nothing however the value was sent.
group_by_depth and the omission are both upstream; the fork mirrored
split_by_depth alongside it faithfully, including the omission. So the column
axis expand/collapse the fork added has the same hole, and pf_app only avoids
it by collapsing columns through a truncated split_by instead.
The patch adds an Option-aware sibling to _apply and applies both fields. It
cannot be built here -- protoc is absent, so the generated protobuf modules
are missing and the crate does not compile for unrelated reasons -- but
cargo check reports nothing against view_config.rs. It sits in ui/vendor with
the rebuild instructions, beside the tarballs it is not yet in.
Meanwhile applyDepth reads the config back after restoring and falls back to
view.set_depth() when the value did not stick, so the buttons work on the
current build. The fallback loses depth on a view rebuild, as it always did;
what is not back is the shim and listeners that used to chase that. The check
clears itself once the engine honours the field.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
4.2 KiB
Vendored Perspective
pf_app runs a patched build of Perspective. Upstream's C++ engine has always
implemented column-axis expand/collapse — t_ctx2::set_depth(HEADER_COLUMN, …)
and open/close(HEADER_COLUMN, idx) are fully written — but nothing above C++
could reach it: set_column_pivot_depth() was never called, and
View<t_ctx2>::expand/collapse hardcoded HEADER_ROW. The patch is wiring, not
new engine logic.
It buys two things the released packages cannot do at all:
split_by_depthinViewConfig, thesplit_bycounterpart togroup_by_depthexpand_column()/collapse_column(), so one column branch can fold to its subtotal while its siblings stay expanded — the Excel behaviour
Source: https://github.com/fleetside72/perspective, branch
column-axis-expand-collapse. See PROVENANCE.txt for the exact commit these
tarballs were built from.
Why tarballs and not npm
The feature is not released upstream. Until it is, the four packages are built
from the fork and committed here as npm tarballs. npm install expands them
exactly as it expands anything from the registry — no special tooling, and
pf.sh deploy works unchanged. A deploy machine needs node and nothing else:
no emscripten, no cmake, no protoc, no Rust.
All four move together, never a subset. Perspective couples loader, package
versions, data format and apache-arrow; vendoring a partial set reintroduces
exactly the drift that causes trouble.
Changing the engine
./rebuild-perspective.sh # builds the fork, repacks, rewrites PROVENANCE.txt
cd .. && npm install
git add vendor && git commit
Push the fork first — the script warns if the source tree is dirty, because a tarball built from uncommitted code has no recoverable source.
The build itself needs cmake >= 3.29.5, protoc >= 22 (its version silently selects which protobuf source tree gets cloned), pnpm, and the Rust nightly the repo pins. Roughly 40 minutes cold. Only ever on a machine changing the engine.
Getting rid of this
This is a fork, with the maintenance that implies. The exit is upstream taking
the change — the patch is small and additive, and the engine work is already
theirs. When a release ships it, delete this directory and put normal version
ranges back in ui/package.json.
Pending patch: depth fields on a config update
0001-apply-depth-fields-on-config-update.patch is not in the vendored
tarballs yet. It fixes an upstream bug in
rust/perspective-client/src/rust/config/view_config.rs:
ViewConfig::apply_update applies ten fields and neither group_by_depth
nor split_by_depth is among them. So a depth can be set when a view is
created (table.view({ group_by_depth: 1 }) — which is what the fork's own
depth_test.mjs exercises) but never through restore(), which is how a
viewer changes its own configuration. The field arrives, deserializes, and is
discarded before the engine sees it.
group_by_depth and the omission are both upstream; the fork mirrored
split_by_depth alongside it faithfully, including the omission.
Note the semantics, from server.cpp:
ctx1->set_depth(row_pivot_depth - 1); // one-sided
ctx2->set_depth(t_header::HEADER_ROW, row_pivot_depth - 1); // two-sided
The config field counts levels to show; view.set_depth() counts the
boundary below them. So group_by_depth: n equals set_depth(n - 1), and
Forecast.jsx sends d + 1.
To apply:
cd $PSP_DIR # default ~/perspective
git apply /path/to/pf_app/ui/vendor/0001-apply-depth-fields-on-config-update.patch
./ui/vendor/rebuild-perspective.sh
cd ui && npm install
cargo check on this patch was clean — the 125 errors it reports without
protoc installed are unresolved generated protobuf modules, none of them in
view_config.rs.
Until the rebuild lands, applyDepth() in Forecast.jsx reads the config back
after restoring it and falls back to the imperative view.set_depth() when the
value did not stick. That fallback loses the depth whenever the viewer rebuilds
its view; the declarative path does not, which is the point of the patch. The
check is cheap and self-clearing — once the engine honours the field, the
fallback stops running on its own.