Observation measured while repairing #7349 (PR #7377) on origin/maind53e472. Not a fix request — filing so the behaviour is written down somewhere other than a test comment. Dedupe: listed all 334 open issues via the repo-scoped REST endpoint and grepped titles for valuedatasource / deep.clone / JSON.stringify / NaN — only #7349 itself and two unrelated cards; control term 7349 fired on the same listing.
What was measured
packages/core/src/adapters/ValueDataSource.ts, constructor:
// Deep clone to prevent external mutationthis.items=JSON.parse(JSON.stringify(config.items));
The intent (isolating the adapter's copy from caller mutation) is sound. The mechanism is lossy, and silently so:
input [{id:'NaN', v:NaN}, {id:'undefined', v:undefined}, {id:'array', v:[]}]
stored [{"id":"NaN","v":null}, {"id":"undefined"}, {"id":"array","v":[]}]
NaN and Infinity are stored as null- a key whose value is
undefined is dropped, so "explicitly undefined" and "absent" become indistinguishable - a
Date becomes an ISO string, and stops comparing as a date - functions,
Symbol keys and Map / Set values are dropped or emptied
Why it surfaced now, and why it is mild
It was invisible before #7349 because the matcher excluded nothing — no filter ever ran, so no coercion could change an answer. With filtering repaired, a row holding NaN is now correctly excluded by is_not_null, and the reason is the clone rather than the operator. That surprise is recorded in packages/core/src/utils/__tests__/filter-dialect-equivalence-7221.test.ts.
For the adapter's declared job the loss is mostly theoretical: provider: 'value' is fed viewData.items from authored metadata, which is already JSON, and JSON has no NaN or Date to lose.
The two in-repo call sites that construct one programmatically are where it could bite, since their inputs are runtime objects rather than parsed JSON:
packages/plugin-designer/src/ObjectManager.tsx:101 — new ValueDataSource({ items: displayObjects })packages/plugin-designer/src/FieldDesigner.tsx:152 — new ValueDataSource({ items: filteredFields })
A Date-valued field reaching either would be stored as a string, sort as a string, and render as a string. Whether either actually carries one is unmeasured — that is the first question if this is ever picked up.
If it is ever worth acting on
structuredClone is available in every runtime this package targets and preserves Date, Map, Set, NaN and explicit undefined. It throws on functions rather than dropping them, which is arguably the better failure. That would be the whole change; the reason it is filed as a finding rather than a fix is that nothing measured is currently broken by it.
Observation measured while repairing #7349 (PR #7377) on
origin/maind53e472. Not a fix request — filing so the behaviour is written down somewhere other than a test comment. Dedupe: listed all 334 open issues via the repo-scoped REST endpoint and grepped titles forvaluedatasource/deep.clone/JSON.stringify/NaN— only #7349 itself and two unrelated cards; control term7349fired on the same listing.What was measured
packages/core/src/adapters/ValueDataSource.ts, constructor:The intent (isolating the adapter's copy from caller mutation) is sound. The mechanism is lossy, and silently so:
NaNandInfinityare stored asnullundefinedis dropped, so "explicitly undefined" and "absent" become indistinguishableDatebecomes an ISO string, and stops comparing as a dateSymbolkeys andMap/Setvalues are dropped or emptiedWhy it surfaced now, and why it is mild
It was invisible before #7349 because the matcher excluded nothing — no filter ever ran, so no coercion could change an answer. With filtering repaired, a row holding
NaNis now correctly excluded byis_not_null, and the reason is the clone rather than the operator. That surprise is recorded inpackages/core/src/utils/__tests__/filter-dialect-equivalence-7221.test.ts.For the adapter's declared job the loss is mostly theoretical:
provider: 'value'is fedviewData.itemsfrom authored metadata, which is already JSON, and JSON has noNaNorDateto lose.The two in-repo call sites that construct one programmatically are where it could bite, since their inputs are runtime objects rather than parsed JSON:
packages/plugin-designer/src/ObjectManager.tsx:101—new ValueDataSource({ items: displayObjects })packages/plugin-designer/src/FieldDesigner.tsx:152—new ValueDataSource({ items: filteredFields })A
Date-valued field reaching either would be stored as a string, sort as a string, and render as a string. Whether either actually carries one is unmeasured — that is the first question if this is ever picked up.If it is ever worth acting on
structuredCloneis available in every runtime this package targets and preservesDate,Map,Set,NaNand explicitundefined. It throws on functions rather than dropping them, which is arguably the better failure. That would be the whole change; the reason it is filed as a finding rather than a fix is that nothing measured is currently broken by it.