ggaction 0.0.15 → 0.0.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (236) hide show
  1. package/CHANGELOG.md +68 -0
  2. package/README.md +22 -2
  3. package/knowledge/action-cards.json +1 -1
  4. package/knowledge/intent-taxonomy.json +1 -1
  5. package/knowledge/mcp-resources.json +1 -1
  6. package/knowledge/task-packet.schema.json +1 -1
  7. package/knowledge/task-resolver.js +1 -1
  8. package/package.json +33 -6
  9. package/src/BasicChartProgram.js +3 -1
  10. package/src/ChartProgram.js +2 -0
  11. package/src/accessibility.js +157 -0
  12. package/src/actions/boxPlots/components.js +6 -8
  13. package/src/actions/boxPlots/create.js +4 -5
  14. package/src/actions/boxPlots/edit.js +3 -4
  15. package/src/actions/boxPlots/materialize.js +1 -1
  16. package/src/actions/canvas/actions.js +3 -3
  17. package/src/actions/canvas/fitting.js +1 -1
  18. package/src/actions/categoryOrder/index.js +6 -8
  19. package/src/actions/charts/area.js +1 -1
  20. package/src/actions/charts/bar.js +1 -1
  21. package/src/actions/charts/beeswarm.js +1 -1
  22. package/src/actions/charts/density.js +1 -1
  23. package/src/actions/charts/ecdf.js +2 -2
  24. package/src/actions/charts/endpoints.js +4 -4
  25. package/src/actions/charts/heatmap.js +1 -1
  26. package/src/actions/charts/histogram.js +1 -1
  27. package/src/actions/charts/horizon.js +1 -1
  28. package/src/actions/charts/interval-regression.js +2 -2
  29. package/src/actions/charts/line.js +1 -1
  30. package/src/actions/charts/parallel.js +1 -1
  31. package/src/actions/charts/pie.js +1 -1
  32. package/src/actions/charts/polar.js +2 -2
  33. package/src/actions/charts/radar.js +1 -1
  34. package/src/actions/charts/radial.js +2 -2
  35. package/src/actions/charts/raincloud.js +2 -2
  36. package/src/actions/charts/rug-strip.js +2 -2
  37. package/src/actions/charts/scatter.js +1 -1
  38. package/src/actions/composition/actions.js +20 -24
  39. package/src/actions/coordinates/actions.js +1 -1
  40. package/src/actions/coordinates/edit.js +1 -1
  41. package/src/actions/data/basicBin2d.js +4 -5
  42. package/src/actions/data/bin.js +2 -2
  43. package/src/actions/data/bin2d.js +6 -8
  44. package/src/actions/data/bin2dMaterialize.js +4 -5
  45. package/src/actions/data/box.js +4 -4
  46. package/src/actions/data/complete.js +2 -2
  47. package/src/actions/data/computed.js +2 -2
  48. package/src/actions/data/create.js +5 -12
  49. package/src/actions/data/density.js +3 -3
  50. package/src/actions/data/derived.js +10 -14
  51. package/src/actions/data/ecdf.js +2 -2
  52. package/src/actions/data/edit.js +35 -23
  53. package/src/actions/data/filter.js +14 -20
  54. package/src/actions/data/fold.js +2 -2
  55. package/src/actions/data/gradientProfile.js +2 -2
  56. package/src/actions/data/horizon.js +2 -2
  57. package/src/actions/data/impute.js +2 -2
  58. package/src/actions/data/index.js +55 -54
  59. package/src/actions/data/interval.js +2 -2
  60. package/src/actions/data/intervalEdit.js +26 -18
  61. package/src/actions/data/normalize.js +2 -2
  62. package/src/actions/data/regression.js +5 -6
  63. package/src/actions/data/revise.js +48 -0
  64. package/src/actions/data/revisionBindings.js +13 -33
  65. package/src/actions/data/stack.js +2 -2
  66. package/src/actions/data/summary.js +2 -2
  67. package/src/actions/data/timeUnit.js +2 -2
  68. package/src/actions/data/window.js +2 -2
  69. package/src/actions/encodings/angle.js +1 -1
  70. package/src/actions/encodings/appearance.js +4 -4
  71. package/src/actions/encodings/barWidth.js +1 -1
  72. package/src/actions/encodings/channels.js +2 -2
  73. package/src/actions/encodings/color/index.js +1 -1
  74. package/src/actions/encodings/density.js +2 -2
  75. package/src/actions/encodings/histogram.js +1 -1
  76. package/src/actions/encodings/horizon.js +6 -8
  77. package/src/actions/encodings/offset.js +2 -2
  78. package/src/actions/encodings/parallel.js +4 -5
  79. package/src/actions/encodings/pathOrder.js +6 -11
  80. package/src/actions/encodings/position/index.js +4 -4
  81. package/src/actions/encodings/ranged.js +5 -5
  82. package/src/actions/encodings/remove.js +4 -5
  83. package/src/actions/encodings/ruleAppearance.js +1 -1
  84. package/src/actions/encodings/seriesLayout.js +1 -1
  85. package/src/actions/encodings/stroke.js +1 -1
  86. package/src/actions/encodings/strokeDash.js +2 -2
  87. package/src/actions/encodings/text.js +1 -1
  88. package/src/actions/errorBands/create.js +11 -17
  89. package/src/actions/errorBands/edit.js +13 -131
  90. package/src/actions/errorBars/create.js +8 -13
  91. package/src/actions/errorBars/edit.js +10 -121
  92. package/src/actions/facets/actions.js +30 -16
  93. package/src/actions/facets/derive.js +8 -2
  94. package/src/actions/facets/guides.js +4 -5
  95. package/src/actions/facets/replay.js +4 -5
  96. package/src/actions/gradientPlots/components.js +5 -6
  97. package/src/actions/gradientPlots/create.js +4 -5
  98. package/src/actions/gradientPlots/edit.js +4 -5
  99. package/src/actions/gradientPlots/materialize.js +2 -2
  100. package/src/actions/gradientPlots/rebind.js +4 -5
  101. package/src/actions/guides/axes/axes.js +23 -4
  102. package/src/actions/guides/axes/axis.js +2 -2
  103. package/src/actions/guides/axes/edit.js +2 -2
  104. package/src/actions/guides/axes/labels.js +9 -9
  105. package/src/actions/guides/axes/lines.js +9 -7
  106. package/src/actions/guides/axes/parallel/lifecycle.js +13 -13
  107. package/src/actions/guides/axes/parallel.js +5 -5
  108. package/src/actions/guides/axes/remove.js +4 -4
  109. package/src/actions/guides/axes/tickGroups.js +4 -4
  110. package/src/actions/guides/axes/ticks.js +13 -4
  111. package/src/actions/guides/axes/titles.js +10 -10
  112. package/src/actions/guides/grids/grid.js +18 -29
  113. package/src/actions/guides/guides.js +1 -1
  114. package/src/actions/guides/legends/blocks.js +1 -1
  115. package/src/actions/guides/legends/categorical/actions.js +4 -4
  116. package/src/actions/guides/legends/categorical/components.js +38 -33
  117. package/src/actions/guides/legends/categorical/layout.js +1 -1
  118. package/src/actions/guides/legends/categorical/symbols.js +27 -30
  119. package/src/actions/guides/legends/continuous/common.js +46 -8
  120. package/src/actions/guides/legends/continuous/gradient.js +89 -155
  121. package/src/actions/guides/legends/continuous/interval.js +13 -13
  122. package/src/actions/guides/legends/continuous/opacity.js +30 -79
  123. package/src/actions/guides/legends/continuous/stroke.js +22 -322
  124. package/src/actions/guides/legends/edit.js +1 -1
  125. package/src/actions/guides/legends/focused.js +5 -5
  126. package/src/actions/guides/legends/lane.js +6 -6
  127. package/src/actions/guides/legends/remove.js +4 -5
  128. package/src/actions/guides/legends/size.js +21 -82
  129. package/src/actions/guides/legends/strokeWidth.js +17 -77
  130. package/src/actions/guides/polar/axes/facade.js +4 -4
  131. package/src/actions/guides/polar/axes/labels.js +5 -5
  132. package/src/actions/guides/polar/axes/lines.js +9 -15
  133. package/src/actions/guides/polar/axes/ticks.js +9 -15
  134. package/src/actions/guides/polar/axes/titles.js +5 -5
  135. package/src/actions/guides/polar/grids.js +11 -13
  136. package/src/actions/index.js +2 -0
  137. package/src/actions/intervals/revision.js +126 -0
  138. package/src/actions/marks/arc/actions.js +3 -3
  139. package/src/actions/marks/area/actions.js +4 -4
  140. package/src/actions/marks/bar/create.js +1 -1
  141. package/src/actions/marks/bar/edit.js +1 -1
  142. package/src/actions/marks/bar/materialize.js +12 -38
  143. package/src/actions/marks/line/actions.js +3 -3
  144. package/src/actions/marks/point/create.js +1 -1
  145. package/src/actions/marks/point/edit.js +1 -1
  146. package/src/actions/marks/point/jitter.js +6 -8
  147. package/src/actions/marks/point/materialize.js +16 -24
  148. package/src/actions/marks/point/packing.js +6 -8
  149. package/src/actions/marks/rect/actions.js +3 -3
  150. package/src/actions/marks/references.js +8 -10
  151. package/src/actions/marks/remove.js +5 -49
  152. package/src/actions/marks/rule/actions.js +4 -4
  153. package/src/actions/marks/text/actions.js +5 -5
  154. package/src/actions/marks/text/layout.js +12 -20
  155. package/src/actions/marks/text/removal.js +1 -1
  156. package/src/actions/marks/text/selection.js +4 -5
  157. package/src/actions/marks/tick/actions.js +3 -3
  158. package/src/actions/primitives/createGraphics.js +5 -4
  159. package/src/actions/primitives/editGraphics.js +5 -4
  160. package/src/actions/primitives/graphicProperties.js +6 -0
  161. package/src/actions/primitives/semantic.js +10 -3
  162. package/src/actions/primitives/semanticAction.js +7 -4
  163. package/src/actions/primitives/semanticValidation/dataset.js +2 -4
  164. package/src/actions/regression/components.js +10 -14
  165. package/src/actions/regression/create.js +3 -4
  166. package/src/actions/regression/edit.js +3 -4
  167. package/src/actions/resources/remove.js +12 -11
  168. package/src/actions/scales/create.js +1 -1
  169. package/src/actions/scales/edit.js +1 -1
  170. package/src/actions/scales/materialize.js +1 -1
  171. package/src/actions/scales/offset.js +2 -2
  172. package/src/actions/scales/parallel.js +1 -1
  173. package/src/actions/scales/quantitativeColor.js +4 -5
  174. package/src/actions/selection/actions.js +25 -36
  175. package/src/actions/textMetrics/index.js +56 -0
  176. package/src/actions/theme/actions.js +2 -2
  177. package/src/actions/theme/reconcile.js +65 -121
  178. package/src/actions/titles/actions.js +8 -8
  179. package/src/actions/titles/resolve.js +3 -3
  180. package/src/actions/violinPlots/create.js +1 -1
  181. package/src/actions/violinPlots/edit.js +1 -1
  182. package/src/core/action.js +107 -35
  183. package/src/core/diagnostics.js +16 -0
  184. package/src/core/extensionRegistry.js +27 -0
  185. package/src/core/font.js +18 -0
  186. package/src/core/identifiers.js +5 -4
  187. package/src/core/immutable.js +10 -3
  188. package/src/core/optionRequirements.js +8 -0
  189. package/src/core/programState.js +1 -1
  190. package/src/core/resourceReferences.js +15 -6
  191. package/src/core/textMetricProfile.js +28 -0
  192. package/src/core/textMetrics.js +24 -3
  193. package/src/core/validation.js +22 -10
  194. package/src/diagnostics.js +1 -0
  195. package/src/grammar/impute.js +3 -2
  196. package/src/grammar/scales/types.js +8 -0
  197. package/src/grammar/schemas/graphicBounds.js +11 -11
  198. package/src/layout/labels.js +11 -10
  199. package/src/layout/legend.js +4 -4
  200. package/src/layout/legendItems.js +6 -6
  201. package/src/layout/text.js +10 -9
  202. package/src/layout/title.js +9 -9
  203. package/src/materialization/facetGuides/placement.js +1 -1
  204. package/src/materialization/facetGuides/preparation.js +1 -1
  205. package/src/materialization/facetHeaders.js +11 -10
  206. package/src/materialization/guides/layout.js +3 -3
  207. package/src/materialization/scaleGuideDependencies.js +10 -0
  208. package/src/materialization/selection/items/common.js +1 -1
  209. package/src/materialization/text.js +2 -2
  210. package/src/materialization/typography.js +31 -0
  211. package/src/mcp/cli.js +5 -3
  212. package/src/persistence/codec.js +65 -0
  213. package/src/persistence/validation.js +185 -0
  214. package/src/persistence.js +74 -0
  215. package/src/renderers/canvas/index.js +5 -4
  216. package/src/renderers/nativeBackend.js +10 -0
  217. package/src/renderers/options.js +13 -0
  218. package/src/renderers/pdf.js +25 -54
  219. package/src/renderers/png.js +22 -17
  220. package/src/renderers/svg.js +10 -14
  221. package/src/renderers/text.js +1 -11
  222. package/src/selectors/coordinates.js +3 -1
  223. package/src/selectors/datasets.js +8 -6
  224. package/src/selectors/layers.js +6 -4
  225. package/src/selectors/markOwners.js +46 -0
  226. package/src/selectors/scales.js +6 -4
  227. package/src/theme/defaults.js +2 -1
  228. package/src/version.js +2 -0
  229. package/types/accessibility.d.ts +37 -0
  230. package/types/basic.d.ts +4 -2
  231. package/types/diagnostics.d.ts +15 -0
  232. package/types/index.d.ts +5 -0
  233. package/types/pdf.d.ts +9 -0
  234. package/types/persistence.d.ts +7 -0
  235. package/types/png.d.ts +9 -0
  236. package/types/program.d.ts +34 -1
@@ -138,13 +138,7 @@ export function planIntervalRoleData(program, {
138
138
  };
139
139
  }
140
140
 
141
- export function planIntervalEdit(program, {
142
- owner,
143
- data,
144
- consumers,
145
- statistics,
146
- operation
147
- }) {
141
+ export function validateIntervalStatistics(statistics, operation) {
148
142
  if (!isPlainObject(statistics)) {
149
143
  throw new TypeError(`${operation} statistics must be a plain object.`);
150
144
  }
@@ -154,16 +148,9 @@ export function planIntervalEdit(program, {
154
148
  `${operation} statistics requires center, extent, method, or level.`
155
149
  );
156
150
  }
157
- const previous = findDataset(program, data);
158
- const transform = previous?.transform?.length === 1
159
- ? previous.transform[0]
160
- : undefined;
161
- if (transform?.type !== "interval") {
162
- throw new Error(
163
- `${operation} statistics requires a statistical interval owner; ` +
164
- "explicit interval fields cannot be converted by edit."
165
- );
166
- }
151
+ }
152
+
153
+ export function mergeIntervalStatistics(transform, statistics) {
167
154
  const center = Object.hasOwn(statistics, "center")
168
155
  ? statistics.center
169
156
  : transform.center;
@@ -181,7 +168,28 @@ export function planIntervalEdit(program, {
181
168
  } else if (extent === "ci" && transform.extent === "ci") {
182
169
  raw.level = transform.level;
183
170
  }
184
- const parameters = normalizeIntervalParameters(raw);
171
+ return normalizeIntervalParameters(raw);
172
+ }
173
+
174
+ export function planIntervalEdit(program, {
175
+ owner,
176
+ data,
177
+ consumers,
178
+ statistics,
179
+ operation
180
+ }) {
181
+ validateIntervalStatistics(statistics, operation);
182
+ const previous = findDataset(program, data);
183
+ const transform = previous?.transform?.length === 1
184
+ ? previous.transform[0]
185
+ : undefined;
186
+ if (transform?.type !== "interval") {
187
+ throw new Error(
188
+ `${operation} statistics requires a statistical interval owner; ` +
189
+ "explicit interval fields cannot be converted by edit."
190
+ );
191
+ }
192
+ const parameters = mergeIntervalStatistics(transform, statistics);
185
193
  const current = {
186
194
  center: transform.center,
187
195
  extent: transform.extent,
@@ -9,14 +9,14 @@ const OPTIONS = Object.freeze([
9
9
  "variance", "zeroDenominator", "baseline", "sortBy"
10
10
  ]);
11
11
 
12
- export const materializeNormalizedData = derivedMaterializer(
12
+ export const materializeNormalizedData = /* @__PURE__ */ derivedMaterializer(
13
13
  "materializeNormalizedData",
14
14
  "Materialize one immutable grouped normalization dataset.",
15
15
  "normalize",
16
16
  deriveNormalizedRows
17
17
  );
18
18
 
19
- export const createNormalizedData = derivedCreator(
19
+ export const createNormalizedData = /* @__PURE__ */ derivedCreator(
20
20
  "createNormalizedData",
21
21
  "Create a row-preserving grouped normalization dataset.",
22
22
  OPTIONS,
@@ -1,6 +1,6 @@
1
- import { action } from "../../core/action.js";
1
+ import { closedAction } from "../../core/action.js";
2
2
  import { validateUserId } from "../../core/identifiers.js";
3
- import { validateKeys } from "../../core/validation.js";
3
+
4
4
  import {
5
5
  deriveRegression,
6
6
  normalizeRegressionTransform
@@ -13,7 +13,7 @@ const OPTIONS = Object.freeze([
13
13
  "confidenceMethod", "level", "confidence", "interval"
14
14
  ]);
15
15
 
16
- export const materializeRegressionData = derivedMaterializer(
16
+ export const materializeRegressionData = /* @__PURE__ */ derivedMaterializer(
17
17
  "materializeRegressionData",
18
18
  "Materialize one regression derived dataset.",
19
19
  "regression",
@@ -31,10 +31,9 @@ export const materializeRegressionData = derivedMaterializer(
31
31
  })
32
32
  );
33
33
 
34
- export const createRegressionData = action(
35
- { op: "createRegressionData", description: "Create grouped regression values and optional interval bounds." },
34
+ export const createRegressionData = /* @__PURE__ */ closedAction(
35
+ { op: "createRegressionData", description: "Create grouped regression values and optional interval bounds." }, OPTIONS,
36
36
  function (args = {}) {
37
- validateKeys(args, OPTIONS, "createRegressionData");
38
37
  const id = validateUserId(args.id, "Regression dataset id");
39
38
  const requestedSource = validateUserId(
40
39
  args.source ?? this.context.currentData,
@@ -0,0 +1,48 @@
1
+ import { closedAction } from "../../core/action.js";
2
+ import { validateUserId } from "../../core/identifiers.js";
3
+
4
+ import { requireDataset } from "../../selectors/datasets.js";
5
+ import { requireLayer } from "../../selectors/layers.js";
6
+ import { applyRevisionPlan, buildSourceRevisionPlan } from "./edit.js";
7
+ import { resolveStoredSelection } from "../../materialization/selection/state.js";
8
+ import { withGuideLayoutTransaction } from "../../materialization/guides/layout.js";
9
+
10
+ let reviseFacet;
11
+
12
+ export function registerFacetDataRevision(handler) {
13
+ reviseFacet = handler;
14
+ }
15
+
16
+ export function reviseUnitData(program, { source, id, values }) {
17
+ const plan = buildSourceRevisionPlan(program, source, id);
18
+ const created = program.createData({ id, values });
19
+ const next = withGuideLayoutTransaction(created, candidate =>
20
+ applyRevisionPlan(candidate, undefined, plan, { retain: new Set([source]) }));
21
+ for (const [selection, config] of Object.entries(next.materializationConfigs.selections ?? {})) {
22
+ if (plan.replacements.has(requireLayer(program, config.target).data)) {
23
+ resolveStoredSelection(next, selection);
24
+ }
25
+ }
26
+ return { program: next, plan };
27
+ }
28
+
29
+ export const reviseData = /* @__PURE__ */ closedAction(
30
+ { op: "reviseData", description: "Revise source data and its dependent chart.", scope: "any" }, ["source", "id", "values"],
31
+ function (args = {}) {
32
+ const source = validateUserId(args.source, "Source dataset id");
33
+ const id = validateUserId(args.id, "Revision dataset id");
34
+ if (this.compositionSpec !== undefined && this.compositionSpec.type !== "facet") {
35
+ throw new Error("Revise an explicit child, then use replaceCompositionChild for concat.");
36
+ }
37
+ const original = requireDataset(this, source);
38
+ if (original.source !== undefined || !Array.isArray(original.values)) {
39
+ throw new Error(`Source "${source}" must be a materialized original dataset.`);
40
+ }
41
+ const apply = this.compositionSpec === undefined
42
+ ? program => reviseUnitData(program, { source, id, values: args.values }).program
43
+ : program => reviseFacet(program, { source, id, values: args.values });
44
+ // The entire dependent materialization must succeed before returning a revision.
45
+ apply(this);
46
+ return apply(this);
47
+ }
48
+ );
@@ -1,11 +1,7 @@
1
- import { isPlainObject } from "../../core/immutable.js";
1
+ import { collectDataOwnerReferences, collectMarkConfigReferences } from "../../core/resourceReferences.js";
2
2
  import { datasetTransformOutputRoles } from "../../grammar/transforms.js";
3
3
  import { requireLayer } from "../../selectors/layers.js";
4
4
 
5
- const DATA_REFERENCE_KEYS = new Set([
6
- "data", "dataset", "dataId", "filteredData", "originalData",
7
- "outlierDataId", "profileId", "source", "summaryId"
8
- ]);
9
5
 
10
6
  export function outputFieldChanges(previous, next) {
11
7
  const before = datasetTransformOutputRoles(previous);
@@ -107,39 +103,23 @@ export function rebindLayerOutputFields(program, id, changes) {
107
103
  return next;
108
104
  }
109
105
 
110
- function replaceReferences(value, replacements, key) {
111
- if (Array.isArray(value)) {
112
- let changed = false;
113
- const items = value.map(item => {
114
- const next = replaceReferences(item, replacements);
115
- changed ||= next !== item;
116
- return next;
117
- });
118
- return changed ? items : value;
119
- }
120
- if (!isPlainObject(value)) {
121
- return DATA_REFERENCE_KEYS.has(key) && replacements.has(value)
122
- ? replacements.get(value)
123
- : value;
124
- }
125
- let changed = false;
126
- const result = {};
127
- for (const [childKey, child] of Object.entries(value)) {
128
- const next = replaceReferences(child, replacements, childKey);
129
- changed ||= next !== child;
130
- result[childKey] = next;
131
- }
132
- return changed ? result : value;
106
+ function replaceAtPath(value, [key, ...rest], replacement) {
107
+ const result = Array.isArray(value) ? [...value] : { ...value };
108
+ Object.defineProperty(result, key, { value: rest.length === 0
109
+ ? replacement : replaceAtPath(value[key], rest, replacement),
110
+ enumerable: true, configurable: true, writable: true });
111
+ return result;
133
112
  }
134
113
 
135
114
  export function rebindMaterializationDataReferences(program, replacements) {
136
115
  if (replacements.size === 0) return program;
137
116
  let next = program;
138
- for (const [key, config] of Object.entries(program.materializationConfigs)) {
139
- const replaced = replaceReferences(config, replacements, key);
140
- if (replaced !== config) {
141
- next = next._withMaterializationConfig([key], replaced);
142
- }
117
+ for (const ref of [...collectMarkConfigReferences(program), ...collectDataOwnerReferences(program)]) {
118
+ if (ref.kind !== "data" || !replacements.has(ref.id)) continue;
119
+ const path = ref.ownerKind === "markConfig" ? ["marks", ref.ownerId, ...ref.path] : ref.path;
120
+ const [root, ...rest] = path;
121
+ next = next._withMaterializationConfig([root],
122
+ replaceAtPath(next.materializationConfigs[root], rest, replacements.get(ref.id)));
143
123
  }
144
124
  return next;
145
125
  }
@@ -8,14 +8,14 @@ const OPTIONS = Object.freeze([
8
8
  "id", "source", "category", "group", "value", "mode", "as"
9
9
  ]);
10
10
 
11
- export const materializeStackData = derivedMaterializer(
11
+ export const materializeStackData = /* @__PURE__ */ derivedMaterializer(
12
12
  "materializeStackData",
13
13
  "Materialize one immutable category/series stack dataset.",
14
14
  "stack",
15
15
  deriveStackRows
16
16
  );
17
17
 
18
- export const createStackData = derivedCreator(
18
+ export const createStackData = /* @__PURE__ */ derivedCreator(
19
19
  "createStackData",
20
20
  "Create reusable start, end, value, and share stack rows.",
21
21
  OPTIONS,
@@ -8,14 +8,14 @@ const OPTIONS = Object.freeze([
8
8
  "id", "source", "groupBy", "aggregates", "members", "weight"
9
9
  ]);
10
10
 
11
- export const materializeSummaryData = derivedMaterializer(
11
+ export const materializeSummaryData = /* @__PURE__ */ derivedMaterializer(
12
12
  "materializeSummaryData",
13
13
  "Materialize one immutable grouped summary dataset.",
14
14
  "summary",
15
15
  deriveSummaryRows
16
16
  );
17
17
 
18
- export const createSummaryData = derivedCreator(
18
+ export const createSummaryData = /* @__PURE__ */ derivedCreator(
19
19
  "createSummaryData",
20
20
  "Create reusable grouped aggregate values and provenance.",
21
21
  OPTIONS,
@@ -9,14 +9,14 @@ const OPTIONS = Object.freeze([
9
9
  "weekStartsOn", "weekRule"
10
10
  ]);
11
11
 
12
- export const materializeTimeUnitData = derivedMaterializer(
12
+ export const materializeTimeUnitData = /* @__PURE__ */ derivedMaterializer(
13
13
  "materializeTimeUnitData",
14
14
  "Materialize one immutable UTC time-unit dataset.",
15
15
  "timeUnit",
16
16
  deriveTimeUnitRows
17
17
  );
18
18
 
19
- export const createTimeUnitData = derivedCreator(
19
+ export const createTimeUnitData = /* @__PURE__ */ derivedCreator(
20
20
  "createTimeUnitData",
21
21
  "Create immutable UTC calendar bucket values.",
22
22
  OPTIONS,
@@ -8,14 +8,14 @@ const OPTIONS = Object.freeze([
8
8
  "id", "source", "partitionBy", "sortBy", "operations", "temporalUnit"
9
9
  ]);
10
10
 
11
- export const materializeWindowData = derivedMaterializer(
11
+ export const materializeWindowData = /* @__PURE__ */ derivedMaterializer(
12
12
  "materializeWindowData",
13
13
  "Materialize one immutable window-derived dataset.",
14
14
  "window",
15
15
  deriveWindowRows
16
16
  );
17
17
 
18
- export const createWindowData = derivedCreator(
18
+ export const createWindowData = /* @__PURE__ */ derivedCreator(
19
19
  "createWindowData",
20
20
  "Create immutable partitioned window values.",
21
21
  OPTIONS,
@@ -14,7 +14,7 @@ function rematerialize(program, layer, target) {
14
14
  : program.rematerializePointMark({ id: target });
15
15
  }
16
16
 
17
- export const encodeAngle = action(
17
+ export const encodeAngle = /* @__PURE__ */ action(
18
18
  {
19
19
  op: "encodeAngle",
20
20
  description: "Assign direct clockwise degree rotation to point or Tick glyphs."
@@ -79,7 +79,7 @@ function encodeAppearanceField(program, channel, args, operation) {
79
79
  return rematerializeEncoding(next, target, channel, scale.id, layer);
80
80
  }
81
81
 
82
- const encodeRadius = action(
82
+ const encodeRadius = /* @__PURE__ */ action(
83
83
  {
84
84
  op: "encodeRadius",
85
85
  description: "Set a constant graphical radius on a point mark."
@@ -112,7 +112,7 @@ const encodeRadius = action(
112
112
  }
113
113
  );
114
114
 
115
- const encodePointRadius = action(
115
+ const encodePointRadius = /* @__PURE__ */ action(
116
116
  {
117
117
  op: "encodePointRadius",
118
118
  description: "Set a constant graphical radius on a point mark."
@@ -146,7 +146,7 @@ const removePointRadius = /* @__PURE__ */ action(
146
146
  }
147
147
  );
148
148
 
149
- const encodeSize = action(
149
+ const encodeSize = /* @__PURE__ */ action(
150
150
  {
151
151
  op: "encodeSize",
152
152
  description: "Encode a quantitative field as equal-area point size."
@@ -156,7 +156,7 @@ const encodeSize = action(
156
156
  }
157
157
  );
158
158
 
159
- const encodeShape = action(
159
+ const encodeShape = /* @__PURE__ */ action(
160
160
  {
161
161
  op: "encodeShape",
162
162
  description: "Encode a nominal field as point shape."
@@ -10,7 +10,7 @@ import { normalizeBarWidth } from "../../grammar/bars/geometry.js";
10
10
 
11
11
  const OPTIONS = Object.freeze(["band", "pixels", "target"]);
12
12
 
13
- const encodeBarWidth = action(
13
+ const encodeBarWidth = /* @__PURE__ */ action(
14
14
  {
15
15
  op: "encodeBarWidth",
16
16
  description: "Override aggregate or ranged bar width within its category slot."
@@ -299,7 +299,7 @@ function finalScaleIds(before, after, originalLayer, finalLayer, requests) {
299
299
  );
300
300
  }
301
301
 
302
- const rematerializeEncodingScales = action(
302
+ const rematerializeEncodingScales = /* @__PURE__ */ action(
303
303
  {
304
304
  op: "rematerializeEncodingScales",
305
305
  description: "Resolve every scale affected by one atomic encoding assignment."
@@ -390,7 +390,7 @@ function applyEncodingAssignments(program, plan) {
390
390
  return instantiateProgram(plan.state, program.constructor);
391
391
  }
392
392
 
393
- export const encodeChannels = action(
393
+ export const encodeChannels = /* @__PURE__ */ action(
394
394
  {
395
395
  op: "encodeChannels",
396
396
  description: "Atomically assign multiple encoding channels to one mark."
@@ -39,7 +39,7 @@ import {
39
39
 
40
40
  import { applyTemporalUnit } from "../temporal.js";
41
41
 
42
- const encodeColor = action(
42
+ const encodeColor = /* @__PURE__ */ action(
43
43
  {
44
44
  op: "encodeColor",
45
45
  description: "Encode a field as graphical color."
@@ -114,7 +114,7 @@ function applyDensityPosition(program, layerId, definition, groupBy) {
114
114
  return next;
115
115
  }
116
116
 
117
- const encodeDensity = action(
117
+ const encodeDensity = /* @__PURE__ */ action(
118
118
  {
119
119
  op: "encodeDensity",
120
120
  description: "Derive and encode a baseline or categorical kernel-density area."
@@ -259,7 +259,7 @@ function assertGroupingSelectionCompatibility(program, layer, changesGroup) {
259
259
  }
260
260
  }
261
261
 
262
- const editDensity = action(
262
+ const editDensity = /* @__PURE__ */ action(
263
263
  {
264
264
  op: "editDensity",
265
265
  description: "Revise one density transform and rematerialize its consumers."
@@ -6,7 +6,7 @@ const HISTOGRAM_OPTIONS = Object.freeze([
6
6
  "stack", "xScale", "yScale", "weight"
7
7
  ]);
8
8
 
9
- const encodeHistogram = action(
9
+ const encodeHistogram = /* @__PURE__ */ action(
10
10
  {
11
11
  op: "encodeHistogram",
12
12
  description: "Encode a binned count histogram with a configurable layout stack."
@@ -1,6 +1,6 @@
1
- import { action } from "../../core/action.js";
1
+ import { closedAction } from "../../core/action.js";
2
2
  import { validateUserId } from "../../core/identifiers.js";
3
- import { validateOptionObject } from "../../core/validation.js";
3
+
4
4
  import {
5
5
  deriveHorizon,
6
6
  validateHorizonTransform
@@ -109,13 +109,12 @@ function applyScaleDefinition(program, current, definition) {
109
109
  return patch === undefined ? program : program.editScale(patch);
110
110
  }
111
111
 
112
- const editHorizon = action(
112
+ const editHorizon = /* @__PURE__ */ closedAction(
113
113
  {
114
114
  op: "editHorizon",
115
115
  description: "Revise one Horizon transform and rematerialize its consumers."
116
- },
116
+ }, EDIT_OPTIONS,
117
117
  function (args = {}) {
118
- validateOptionObject(args, EDIT_OPTIONS, "editHorizon");
119
118
  if (Object.hasOwn(args, "groupBy") && args.groupBy === undefined) {
120
119
  throw new Error("editHorizon groupBy requires a field string or false.");
121
120
  }
@@ -278,13 +277,12 @@ const editHorizon = action(
278
277
  }
279
278
  );
280
279
 
281
- const encodeHorizon = action(
280
+ const encodeHorizon = /* @__PURE__ */ closedAction(
282
281
  {
283
282
  op: "encodeHorizon",
284
283
  description: "Derive and encode one folded Horizon area."
285
- },
284
+ }, OPTIONS,
286
285
  function (args = {}) {
287
- validateOptionObject(args, OPTIONS, "encodeHorizon");
288
286
  const layer = findHorizonArea(this, args.target);
289
287
  validateUnusedHorizonEncodings(layer);
290
288
  const source = resolveHorizonSource(this, layer, args.source);
@@ -110,8 +110,8 @@ function createOffsetEncoding(channel) {
110
110
  );
111
111
  }
112
112
 
113
- const encodeXOffset = createOffsetEncoding("xOffset");
114
- const encodeYOffset = createOffsetEncoding("yOffset");
113
+ const encodeXOffset = /* @__PURE__ */ createOffsetEncoding("xOffset");
114
+ const encodeYOffset = /* @__PURE__ */ createOffsetEncoding("yOffset");
115
115
 
116
116
  export function registerOffsetEncodingAction(ProgramClass) {
117
117
  ProgramClass.prototype.encodeXOffset = encodeXOffset;
@@ -1,5 +1,5 @@
1
- import { action } from "../../core/action.js";
2
- import { validateOptionObject } from "../../core/validation.js";
1
+ import { closedAction } from "../../core/action.js";
2
+
3
3
  import {
4
4
  normalizeParallelDimensions,
5
5
  validateParallelKeyField,
@@ -19,13 +19,12 @@ const OPTIONS = Object.freeze([
19
19
  "target", "coordinate", "dimensions", "key", "missing"
20
20
  ]);
21
21
 
22
- export const encodeParallelCoordinates = action(
22
+ export const encodeParallelCoordinates = /* @__PURE__ */ closedAction(
23
23
  {
24
24
  op: "encodeParallelCoordinates",
25
25
  description: "Atomically encode ordered Parallel-coordinate dimensions."
26
- },
26
+ }, OPTIONS,
27
27
  function (args = {}) {
28
- validateOptionObject(args, OPTIONS, "encodeParallelCoordinates");
29
28
  const { id: target, dataset, layer } = resolveTarget(
30
29
  this,
31
30
  args.target,
@@ -1,9 +1,6 @@
1
- import { action } from "../../core/action.js";
1
+ import { closedAction } from "../../core/action.js";
2
2
  import { validateUserId } from "../../core/identifiers.js";
3
- import {
4
- validateNonEmptyString,
5
- validateOptionObject
6
- } from "../../core/validation.js";
3
+ import { validateNonEmptyString } from "../../core/validation.js";
7
4
  import { readQuantitativeField } from "../../grammar/scales/index.js";
8
5
  import { validatePathOrderDirection } from "../../grammar/pathOrder.js";
9
6
  import {
@@ -76,13 +73,12 @@ function rematerializePath(program, layer) {
76
73
  : program;
77
74
  }
78
75
 
79
- const encodePathOrder = action(
76
+ const encodePathOrder = /* @__PURE__ */ closedAction(
80
77
  {
81
78
  op: "encodePathOrder",
82
79
  description: "Order vertices within each Cartesian path series."
83
- },
80
+ }, ENCODE_OPTIONS,
84
81
  function (args = {}) {
85
- validateOptionObject(args, ENCODE_OPTIONS, "encodePathOrder");
86
82
  const field = validateNonEmptyString(args.field, "Path order field");
87
83
  const fieldType = args.fieldType ?? "quantitative";
88
84
  if (fieldType !== "quantitative") {
@@ -102,13 +98,12 @@ const encodePathOrder = action(
102
98
  }
103
99
  );
104
100
 
105
- const removePathOrder = action(
101
+ const removePathOrder = /* @__PURE__ */ closedAction(
106
102
  {
107
103
  op: "removePathOrder",
108
104
  description: "Remove explicit path order and restore automatic ordering."
109
- },
105
+ }, REMOVE_OPTIONS,
110
106
  function (args = {}) {
111
- validateOptionObject(args, REMOVE_OPTIONS, "removePathOrder");
112
107
  const layer = resolvePathOrderLayer(this, args.target, { active: true });
113
108
  const next = this.editSemantic({
114
109
  property: `layer[${layer.id}].encoding.pathOrder`,
@@ -141,7 +141,7 @@ function encodePosition(program, channel, args, operation) {
141
141
  return applyDetachedScaleRematerialization(next, [layer]);
142
142
  }
143
143
 
144
- const encodeX = action(
144
+ const encodeX = /* @__PURE__ */ action(
145
145
  {
146
146
  op: "encodeX",
147
147
  description: "Encode a field as horizontal position."
@@ -151,7 +151,7 @@ const encodeX = action(
151
151
  }
152
152
  );
153
153
 
154
- const encodeY = action(
154
+ const encodeY = /* @__PURE__ */ action(
155
155
  {
156
156
  op: "encodeY",
157
157
  description: "Encode a field as vertical position."
@@ -161,7 +161,7 @@ const encodeY = action(
161
161
  }
162
162
  );
163
163
 
164
- const encodeTheta = action(
164
+ const encodeTheta = /* @__PURE__ */ action(
165
165
  {
166
166
  op: "encodeTheta",
167
167
  description: "Encode a field as Polar angle in clockwise degrees."
@@ -171,7 +171,7 @@ const encodeTheta = action(
171
171
  }
172
172
  );
173
173
 
174
- const encodeR = action(
174
+ const encodeR = /* @__PURE__ */ action(
175
175
  {
176
176
  op: "encodeR",
177
177
  description: "Encode a quantitative field as Polar radius."
@@ -159,7 +159,7 @@ function encodeSecondaryPosition(program, channel, args, operation, types) {
159
159
  return next;
160
160
  }
161
161
 
162
- const encodeX2 = action(
162
+ const encodeX2 = /* @__PURE__ */ action(
163
163
  {
164
164
  op: "encodeX2",
165
165
  description: "Encode a secondary horizontal endpoint."
@@ -175,7 +175,7 @@ const encodeX2 = action(
175
175
  }
176
176
  );
177
177
 
178
- const encodeY2 = action(
178
+ const encodeY2 = /* @__PURE__ */ action(
179
179
  {
180
180
  op: "encodeY2",
181
181
  description: "Encode a secondary vertical endpoint."
@@ -222,10 +222,10 @@ function rangeAction(channel) {
222
222
  });
223
223
  }
224
224
 
225
- const encodeYRange = rangeAction("y");
226
- const encodeXRange = rangeAction("x");
225
+ const encodeYRange = /* @__PURE__ */ rangeAction("y");
226
+ const encodeXRange = /* @__PURE__ */ rangeAction("x");
227
227
 
228
- const encodeGroup = action(
228
+ const encodeGroup = /* @__PURE__ */ action(
229
229
  {
230
230
  op: "encodeGroup",
231
231
  description: "Split path geometry by nominal identity fields without a scale."
@@ -1,6 +1,6 @@
1
- import { action } from "../../core/action.js";
1
+ import { closedAction } from "../../core/action.js";
2
2
  import { validateUserId } from "../../core/identifiers.js";
3
- import { validateOptionObject } from "../../core/validation.js";
3
+
4
4
  import {
5
5
  getPositionChannelDefinition,
6
6
  POSITION_ENCODING_CHANNELS
@@ -203,13 +203,12 @@ function rematerializeTarget(program, target) {
203
203
  return next;
204
204
  }
205
205
 
206
- export const removeEncoding = action(
206
+ export const removeEncoding = /* @__PURE__ */ closedAction(
207
207
  {
208
208
  op: "removeEncoding",
209
209
  description: "Remove one semantic encoding and its owned materialized state."
210
- },
210
+ }, OPTIONS,
211
211
  function (args = {}) {
212
- validateOptionObject(args, OPTIONS, "removeEncoding");
213
212
  if (!REMOVABLE_CHANNELS.includes(args.channel)) {
214
213
  throw new Error(
215
214
  `Unsupported removable encoding channel "${args.channel}".`
@@ -19,7 +19,7 @@ const WIDTH_OPTIONS = Object.freeze([
19
19
  "target", "value", "field", "fieldType", "scale"
20
20
  ]);
21
21
 
22
- const encodeStrokeWidth = action(
22
+ const encodeStrokeWidth = /* @__PURE__ */ action(
23
23
  {
24
24
  op: "encodeStrokeWidth",
25
25
  description: "Assign constant or field-driven line or rule stroke width."
@@ -15,7 +15,7 @@ export function stackLayoutMode(stack) {
15
15
  return stack === "normalize" ? "fill" : stack === "center" ? "center" : stack === null ? "overlay" : "stack";
16
16
  }
17
17
 
18
- export const layoutSeries = action({ op: "layoutSeries", description: "Assign series placement independently of color." }, function (args = {}) {
18
+ export const layoutSeries = /* @__PURE__ */ action({ op: "layoutSeries", description: "Assign series placement independently of color." }, function (args = {}) {
19
19
  validateOptions(args, ["target", "mode"], "layoutSeries");
20
20
  const mode = validateColorLayout(args.mode);
21
21
  const { id: target, layer, dataset } = resolveTarget(this, args.target, ["bar", "area"], "series mark");
@@ -101,7 +101,7 @@ function validateStrokeField(dataset, layer, args, scale, temporalUnit) {
101
101
  }
102
102
  }
103
103
 
104
- export const encodeStroke = action(
104
+ export const encodeStroke = /* @__PURE__ */ action(
105
105
  {
106
106
  op: "encodeStroke",
107
107
  description: "Assign constant or field-driven graphical stroke color."