Skip to content

feat: expose per-writer value variants on merged variables#125

Merged
barinali merged 8 commits into
mainfrom
split-value-per-element
Jul 15, 2026
Merged

feat: expose per-writer value variants on merged variables#125
barinali merged 8 commits into
mainfrom
split-value-per-element

Conversation

@barinali

@barinali barinali commented Jul 3, 2026

Copy link
Copy Markdown
Member

Proposed Changes

This pull request aims to introduce a variants property per variable per origin so that individual incarnations of variable writes can be visualized in the user interface.

I have aimed to;

  • non-breaking changes, only additive
  • stick to existing variable contract as a variant
  • merged representation is not altered or removed so that we can stick to the existing autocomplete for feel-editor or possibly other downstreams.

This pull request should enable @bpmn-io/variable-outline to visualize variable incarnations individually rather than merged.

image

This screenshot is subject to iteration. However, you are welcome to share feedback!

The variable-outline branch is not there yet. It'll be linked here once it's created.

Related to camunda/camunda-modeler#5985

Checklist

Ensure you provide everything we need to review your contribution:

  • Contribution meets our definition of done
  • Pull request establishes context
    • Link to related issue(s), i.e. Closes {LINK_TO_ISSUE} or Related to {LINK_TO_ISSUE}
    • Brief textual description of the changes
    • Screenshots or short videos showing UI/UX changes
    • Steps to try out, i.e. using the @bpmn-io/sr tool

barinali added 6 commits July 2, 2026 18:53
Emit FEEL-resolved variable records with the single origin they were
resolved for, snapshotting the value before cross-origin type unions.
Merged output is unchanged; this enables accurate per-writer values.

Related to camunda/camunda-modeler#5985
Merged variables now carry a variants array, one variable-shaped entry
per writing element, so consumers can display individual values instead
of only the merged representation.

Related to camunda/camunda-modeler#5985
Same-named variables in different scopes each keep exactly their own
writers' variants, guarding against cross-scope leakage.

Related to camunda/camunda-modeler#5985
…-merged, and C7 cases

Covers five writers incl. script result expressions, per-writer info on
uncertain expressions, mixed null pre-merged origins, same-element
contribution combining, and the Camunda 7 resolver.

Related to camunda/camunda-modeler#5985
One element writing a variable via a plain and a hierarchical output
mapping yields one variant carrying the combined nested entries.

Related to camunda/camunda-modeler#5985
A variable materialized purely from hierarchical output mappings of one
element yields a synthesized base record with one combined variant.

Related to camunda/camunda-modeler#5985
@barinali
barinali requested review from a team and Copilot July 3, 2026 17:11
@bpmn-io-tasks bpmn-io-tasks Bot added the needs review Review pending label Jul 3, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR adds per-writer variants to merged variable records so downstream consumers (notably @bpmn-io/variable-outline) can visualize individual write “incarnations” without losing the existing merged representation used for autocomplete and other integrations.

Changes:

  • Add variants to merged variables in the base resolver, including recursive editor-format mapping.
  • Adjust FEEL mapping resolution to preserve origin-specific results (so values/types don’t get cross-origin-unioned into a single “writer”).
  • Add extensive test coverage and fixtures for variant behavior across Zeebe + Camunda resolvers, including same-element contribution merging and non-leakage of entries.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
lib/base/VariableResolver.js Collect and maintain per-origin variants during merge; ensure editor-format mapping includes variants.
lib/zeebe/util/feelUtility.js Preserve per-origin resolution results when computing FEEL-mapped variables.
test/assertions.js Extend test matcher utilities to support origin-aware matching and variants assertions.
test/spec/zeebe/ZeebeVariableResolver.spec.js Add resolver-level tests for variants behavior (per-writer, scoping, hierarchical variables, etc.).
test/spec/zeebe/Mappings.spec.js Add mapping-focused tests asserting variant splitting/combining behavior across multiple mapping scenarios.
test/spec/camunda/CamundaVariableResolver.spec.js Add Camunda-side variant exposure test coverage.
test/fixtures/zeebe/mappings/merging.per-element.bpmn New fixture for per-element write scenarios (result expressions / multiple writers).
test/fixtures/zeebe/mappings/merging.same-element.bpmn New fixture for same-element multi-write contribution merging.
test/fixtures/zeebe/mappings/merging.same-element.paths.bpmn New fixture for same-element path-only contributions merging.
README.md Document the new variants property on merged variables.
CHANGELOG.md Note the new feature and FEEL per-origin resolution behavior in unreleased changes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread test/assertions.js Outdated
Comment thread README.md Outdated
barinali added 2 commits July 3, 2026 22:17
The matcher filters by origin since the variants support, so failures
must show it to disambiguate same-named variables.

Related to camunda/camunda-modeler#5985
Aligns the variants example with the README convention of quoting
element ids in origin arrays.

Related to camunda/camunda-modeler#5985
@nikku

nikku commented Jul 7, 2026

Copy link
Copy Markdown
Member

What this delivers is variants per variable, FEEL expression "variable created".

What this does not deliver is variants per expression:

if foo then { "bar": 10 } else 10

Above will still be merged Context|10 - or in other incarnations overridden (by the last value) - [ 10, true, { } ] is of type Context.

Proposed in nikku/lezer-feel#87 is to support that feature "all the way". Above if expression clearly carries 10 | Context { "bar": 10 } as a shape.

Your call to which level you want to support it.

@nikku
nikku self-requested a review July 7, 2026 10:59
@barinali

barinali commented Jul 7, 2026

Copy link
Copy Markdown
Member Author

What this delivers is variants per variable, FEEL expression "variable created".

What this does not deliver is variants per expression:

if foo then { "bar": 10 } else 10

Above will still be merged Context|10 - or in other incarnations overridden (by the last value) - [ 10, true, { } ] is of type Context.

Proposed in nikku/lezer-feel#87 is to support that feature "all the way". Above if expression clearly carries 10 | Context { "bar": 10 } as a shape.

Your call to which level you want to support it.

I think these two differ in what they provide us with;

  • nikku/lezer-feel#87 is to preserve variants of variable resolution as in an conditional expression would resolve in two different shapes and nikku/lezer-feel#87 preserves those shapes.
    • I see this as an enabler on the editor intelligence. For example, this would possibly enable us to integrate a guided autocomplete rather than a blind one. When having a = if foo then { "bar": { "baz": 123 } } else { "def": false }, if I start typing a.foo.bar, then I'd be suggested with .bar rather than .def as I took the path of the first resolution variant.
  • this pull request preserves the assignment values of the variables rather than their resolution variants. So that we can preserve the variants of the variables when multiple elements write into the same variable.
    • This is a supporting feature on the variable lineage where one can have better and easier discovery on a variable's journey as we would be able to display which elements write onto a variable with which assignment value: an enabler for the variable outline panel.

So I am unsure if I would have called nikku/lezer-feel#87 supporting the "feature" "all the way" as these two topics deliver different values in my opinion.

I would suggest we consider this pull request as-is to enable variable-outline and nikku/lezer-feel#87 could be considered later for variable intelligence from the feel-editor (autocomplete) perspective etc.

Nevertheless, as always, I am happy to be corrected in case I happen to deviate from the vision for the sake of variable intelligence.

@nikku nikku left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Good stuff. Let's get this incorporated.

@barinali
barinali merged commit ebd12aa into main Jul 15, 2026
5 checks passed
@bpmn-io-tasks bpmn-io-tasks Bot removed the needs review Review pending label Jul 15, 2026
@barinali
barinali deleted the split-value-per-element branch July 15, 2026 12:32
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.

3 participants