Skip to content

Conversation

@frasercl
Copy link
Contributor

@frasercl frasercl commented Nov 28, 2025

Context

For a while, we've wanted a way to send more data to an opened Vol-E window than could practically fit in URL query parameters — namely, large selections of images and image metadata. Previous passes at this include #516, which got caught up in arcane browser security policies; and #566, which requires an intermediate server, and targets CFE rather than Vol-E. The implementation in this PR happens entirely locally, appears unlikely to run afoul of any cross-origin isolation, and has the convenient bonus of being backwards-compatible with versions of Vol-E that aren't expecting the extra protocol.

Changes

Here's how it works:

  • The new openInVole handler always includes something in the url query param of the Vol-E URL it opens, which ensures Vol-E will always show something even if one of the steps below fails.
  • ...but it also adds new query params: storageid uniquely identifies the message BFF will send to Vol-E, and msgorigin is the origin of the opening BFF window (the slice of the URL from the beginning through the port, i.e. https://bff.allencell.org), which helps with security.
  • On load, Vol-E recognizes that those params are present and uses postMessage to send the value of storageid back to BFF, indicating that it's ready to receive the message content.
  • Once BFF receives that message back from Vol-E, it postMessages back the extra data.

allen-cell-animated/vole-app#467 is the counterpart PR on the Vol-E side. It gets into the details of how Vol-E handles the received message.

Testing

With BFF on this branch...

  • Make a large selection of image files and choose "Open in Vol-E." Expectation: only the "focused" image should open in Vol-E. msgorigin and storageid will be in the URL but unused.
  • Select a small number of image files (~3) and choose "Open in Vol-E". Expectation: this branch is willing to put small multi-scene collections in the URL, so all these images should open at once (the "Scene" slider will be visible in Vol-E's "Clipping" panel). msgorigin and storageid should still be there to send image metadata.
  • Change VOLE_BASE_URL to http://localhost:9020/viewer, and start Vol-E locally on the branch feature/receive-from-bff. Make a large selection of image files and choose "Open in Vol-E." Expectation: subject to the caveats described in Receive multiscenes and metadata from BFF allen-cell-animated/vole-app#467, Vol-E will open the whole image collection, starting on the image that was "focused" in BFF, and data from other columns in BFF will appear in Vol-E's "Metadata" panel.

Comment on lines 348 to 349
// custom hook this, like `useOpenInCfe`?
const openInVole = React.useCallback(async (): Promise<void> => {
Copy link
Contributor Author

@frasercl frasercl Nov 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't end up breaking out a custom hook for this because:

  1. It uses the tiny utility function getFileExtension and I didn't feel like copying it over.
  2. More importantly, it uses openWindowWithMessage. Like I said in that function's docs, it may be useful for opening large collections of data in other apps, and I didn't want it isolated in another file just yet.
  3. The implementation below is just on the edge of feeling okay to include inline, if openInCfe was long enough to break out.

Any of the above could fall the other way for someone else or change in the future though, so I also kept the comment.

"reselect": "4.0.x",
"string-natural-compare": "3.0.x"
"string-natural-compare": "3.0.x",
"uuid": "^13.0.0"
Copy link
Contributor Author

@frasercl frasercl Nov 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was already present somewhere further down the dependency tree, so depending on it explicitly doesn't change much.

Copy link
Contributor

@aswallace aswallace left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thoughts on whether we need to consider url encoding? unsure if it would be an issue here

Also, extremely minor: Vole vs VolE for capitalization? It keeps making me think of rodents

@toloudis
Copy link

toloudis commented Dec 1, 2025

Thoughts on whether we need to consider url encoding? unsure if it would be an issue here

Also, extremely minor: Vole vs VolE for capitalization? It keeps making me think of rodents

I think we should avoid spelling it Vole and should use either VolE or Vol-E pronounced like "volley" like a cute robot character from an animated movie from 2008

@aswallace aswallace requested a review from pgarrison December 1, 2025 22:29
* emphasize that this protocol is both message- and receiver-agnostic, and could be used to send
* large bundles of data to other apps as well.
*/
function openWindowWithMessage(openUrl: URL, message: any): void {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could message bit any more specific? Like perhaps Record<string, any> | undefined?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That any is there to match the signature for postMessage, which can also take any type. Certainly no reason we can't make our own function more specific though.

const allDetails = await fileSelection.fetchAllDetails();
const details = allDetails.filter((detail) => {
const fileExt = getFileExtension(detail);
return fileExt === "zarr" || fileExt === "";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sldy files are sometimes captured in the community as .sldy/ which would become "" here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getFileExtension is unaware of / and would get this right.

...which implies a bigger problem: this will fall over for valid Zarr images without an extension with a . somewhere else in their file path: .../john.doe/valid_zarr. I'll look at making that more robust, including special-casing .sldy/.

@frasercl
Copy link
Contributor Author

frasercl commented Jan 8, 2026

Thoughts on whether we need to consider url encoding? unsure if it would be an issue here

I went down a pretty significant URL encoding rabbit hole in the time this has been open. The results of that on the Vol-E side are at allen-cell-animated/vole-app#473. But my conclusions about encoding on this side are:

  1. Yes, image URLs ought to be encoded before going in the Vol-E url query param.
  2. Ideally, they would all be encoded separately, before being concatenated together into a big list of scenes, but...
  3. ...adding a query param to a URL object automatically encodes the whole thing; this is more trouble than it's worth to circumvent, and it would be a bit silly to double-encode URLs.
  4. URLs will nonetheless have to be double-encoded in the somewhat unlikely event that they contain any of the delimiters Vol-E uses to separate scene and source URLs (+ or ,).

I made some small modifications with 4. in mind.

@frasercl frasercl merged commit 2c1a362 into main Jan 8, 2026
7 checks passed
@frasercl frasercl deleted the feature/vole-open-local branch January 8, 2026 03:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants