ggaction 0.0.13 → 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 (359) hide show
  1. package/CHANGELOG.md +146 -0
  2. package/README.md +41 -12
  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 +39 -7
  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/basic.js +2 -2
  13. package/src/actions/boxPlots/components.js +20 -12
  14. package/src/actions/boxPlots/create.js +4 -5
  15. package/src/actions/boxPlots/edit.js +34 -9
  16. package/src/actions/boxPlots/materialize.js +12 -4
  17. package/src/actions/boxPlots/options.js +48 -16
  18. package/src/actions/canvas/actions.js +3 -3
  19. package/src/actions/canvas/fitting.js +1 -1
  20. package/src/actions/categoryOrder/index.js +21 -12
  21. package/src/actions/charts/area.js +6 -2
  22. package/src/actions/charts/bar.js +3 -2
  23. package/src/actions/charts/beeswarm.js +1 -1
  24. package/src/actions/charts/density.js +7 -3
  25. package/src/actions/charts/ecdf.js +6 -3
  26. package/src/actions/charts/endpoints.js +29 -7
  27. package/src/actions/charts/heatmap.js +3 -2
  28. package/src/actions/charts/histogram.js +5 -4
  29. package/src/actions/charts/horizon.js +4 -2
  30. package/src/actions/charts/interval-regression.js +7 -4
  31. package/src/actions/charts/line.js +4 -2
  32. package/src/actions/charts/parallel.js +9 -3
  33. package/src/actions/charts/pie.js +11 -3
  34. package/src/actions/charts/polar.js +17 -6
  35. package/src/actions/charts/radar.js +9 -3
  36. package/src/actions/charts/radial.js +12 -4
  37. package/src/actions/charts/raincloud.js +2 -2
  38. package/src/actions/charts/rug-strip.js +8 -4
  39. package/src/actions/charts/scatter.js +4 -2
  40. package/src/actions/composition/actions.js +29 -24
  41. package/src/actions/coordinates/actions.js +2 -2
  42. package/src/actions/coordinates/edit.js +76 -0
  43. package/src/actions/data/basicBin2d.js +4 -5
  44. package/src/actions/data/bin.js +3 -3
  45. package/src/actions/data/bin2d.js +63 -193
  46. package/src/actions/data/bin2dMaterialize.js +4 -5
  47. package/src/actions/data/box.js +4 -4
  48. package/src/actions/data/complete.js +26 -0
  49. package/src/actions/data/computed.js +4 -4
  50. package/src/actions/data/create.js +7 -14
  51. package/src/actions/data/density.js +15 -23
  52. package/src/actions/data/derived.js +57 -31
  53. package/src/actions/data/ecdf.js +2 -2
  54. package/src/actions/data/edit.js +551 -0
  55. package/src/actions/data/filter.js +28 -22
  56. package/src/actions/data/fold.js +2 -2
  57. package/src/actions/data/gradientProfile.js +2 -2
  58. package/src/actions/data/horizon.js +2 -2
  59. package/src/actions/data/impute.js +26 -0
  60. package/src/actions/data/index.js +62 -47
  61. package/src/actions/data/interval.js +2 -2
  62. package/src/actions/data/intervalEdit.js +26 -18
  63. package/src/actions/data/normalize.js +27 -0
  64. package/src/actions/data/regression.js +21 -27
  65. package/src/actions/data/revise.js +48 -0
  66. package/src/actions/data/revisionBindings.js +125 -0
  67. package/src/actions/data/shared.js +20 -4
  68. package/src/actions/data/stack.js +2 -2
  69. package/src/actions/data/summary.js +3 -3
  70. package/src/actions/data/timeUnit.js +6 -3
  71. package/src/actions/data/window.js +3 -3
  72. package/src/actions/encodings/angle.js +1 -1
  73. package/src/actions/encodings/appearance.js +4 -4
  74. package/src/actions/encodings/barWidth.js +1 -1
  75. package/src/actions/encodings/channels.js +415 -0
  76. package/src/actions/encodings/color/index.js +3 -2
  77. package/src/actions/encodings/density.js +7 -4
  78. package/src/actions/encodings/histogram.js +4 -3
  79. package/src/actions/encodings/horizon.js +6 -8
  80. package/src/actions/encodings/index.js +4 -0
  81. package/src/actions/encodings/offset.js +22 -15
  82. package/src/actions/encodings/parallel.js +4 -5
  83. package/src/actions/encodings/pathOrder.js +6 -11
  84. package/src/actions/encodings/position/apply.js +53 -7
  85. package/src/actions/encodings/position/index.js +14 -6
  86. package/src/actions/encodings/position/policies/bar.js +9 -0
  87. package/src/actions/encodings/position/resolve.js +24 -7
  88. package/src/actions/encodings/ranged.js +5 -5
  89. package/src/actions/encodings/remove.js +13 -9
  90. package/src/actions/encodings/ruleAppearance.js +2 -24
  91. package/src/actions/encodings/seriesLayout.js +2 -1
  92. package/src/actions/encodings/shared.js +82 -14
  93. package/src/actions/encodings/stroke.js +226 -0
  94. package/src/actions/encodings/strokeDash.js +2 -2
  95. package/src/actions/encodings/text.js +1 -1
  96. package/src/actions/errorBands/create.js +34 -20
  97. package/src/actions/errorBands/edit.js +34 -137
  98. package/src/actions/errorBars/create.js +43 -20
  99. package/src/actions/errorBars/edit.js +29 -125
  100. package/src/actions/facets/actions.js +267 -73
  101. package/src/actions/facets/derive.js +99 -28
  102. package/src/actions/facets/guides.js +4 -5
  103. package/src/actions/facets/replay.js +4 -5
  104. package/src/actions/gradientPlots/components.js +15 -8
  105. package/src/actions/gradientPlots/create.js +4 -5
  106. package/src/actions/gradientPlots/edit.js +18 -9
  107. package/src/actions/gradientPlots/materialize.js +5 -3
  108. package/src/actions/gradientPlots/options.js +10 -2
  109. package/src/actions/gradientPlots/rebind.js +4 -5
  110. package/src/actions/guides/applicability.js +8 -2
  111. package/src/actions/guides/axes/axes.js +23 -4
  112. package/src/actions/guides/axes/axis.js +2 -2
  113. package/src/actions/guides/axes/edit.js +2 -2
  114. package/src/actions/guides/axes/labels.js +67 -21
  115. package/src/actions/guides/axes/lines.js +15 -9
  116. package/src/actions/guides/axes/parallel/lifecycle.js +13 -13
  117. package/src/actions/guides/axes/parallel/resolve.js +6 -2
  118. package/src/actions/guides/axes/parallel.js +5 -5
  119. package/src/actions/guides/axes/remove.js +4 -4
  120. package/src/actions/guides/axes/tickGroups.js +6 -5
  121. package/src/actions/guides/axes/ticks.js +19 -6
  122. package/src/actions/guides/axes/titles.js +21 -13
  123. package/src/actions/guides/grids/grid.js +18 -29
  124. package/src/actions/guides/grids/resolve.js +7 -2
  125. package/src/actions/guides/guides.js +20 -4
  126. package/src/actions/guides/legends/blocks.js +426 -0
  127. package/src/actions/guides/legends/categorical/actions.js +138 -52
  128. package/src/actions/guides/legends/categorical/components.js +55 -45
  129. package/src/actions/guides/legends/categorical/index.js +37 -33
  130. package/src/actions/guides/legends/categorical/layout.js +98 -16
  131. package/src/actions/guides/legends/categorical/options.js +2 -2
  132. package/src/actions/guides/legends/categorical/recipes.js +111 -20
  133. package/src/actions/guides/legends/categorical/resolve.js +12 -8
  134. package/src/actions/guides/legends/categorical/symbols.js +104 -52
  135. package/src/actions/guides/legends/continuous/common.js +76 -20
  136. package/src/actions/guides/legends/continuous/gradient.js +95 -158
  137. package/src/actions/guides/legends/continuous/index.js +2 -0
  138. package/src/actions/guides/legends/continuous/interval.js +21 -16
  139. package/src/actions/guides/legends/continuous/opacity.js +37 -83
  140. package/src/actions/guides/legends/continuous/stroke.js +225 -0
  141. package/src/actions/guides/legends/creation.js +14 -1
  142. package/src/actions/guides/legends/edit.js +159 -60
  143. package/src/actions/guides/legends/focused.js +5 -5
  144. package/src/actions/guides/legends/index.js +2 -0
  145. package/src/actions/guides/legends/lane.js +59 -24
  146. package/src/actions/guides/legends/lifecycle.js +19 -8
  147. package/src/actions/guides/legends/remove.js +17 -8
  148. package/src/actions/guides/legends/sampling.js +140 -0
  149. package/src/actions/guides/legends/size.js +100 -108
  150. package/src/actions/guides/legends/strokeWidth.js +38 -92
  151. package/src/actions/guides/legends/target.js +112 -1
  152. package/src/actions/guides/legends/transition.js +165 -16
  153. package/src/actions/guides/polar/axes/facade.js +8 -8
  154. package/src/actions/guides/polar/axes/labels.js +29 -10
  155. package/src/actions/guides/polar/axes/lines.js +19 -19
  156. package/src/actions/guides/polar/axes/shared.js +16 -0
  157. package/src/actions/guides/polar/axes/ticks.js +10 -16
  158. package/src/actions/guides/polar/axes/titles.js +6 -6
  159. package/src/actions/guides/polar/grids.js +12 -14
  160. package/src/actions/guides/polar/resolve.js +12 -8
  161. package/src/actions/index.js +16 -3
  162. package/src/actions/intervals/revision.js +126 -0
  163. package/src/actions/marks/arc/actions.js +80 -22
  164. package/src/actions/marks/area/actions.js +38 -13
  165. package/src/actions/marks/area/materialize.js +17 -1
  166. package/src/actions/marks/bar/create.js +12 -3
  167. package/src/actions/marks/bar/edit.js +21 -4
  168. package/src/actions/marks/bar/materialize.js +34 -40
  169. package/src/actions/marks/index.js +10 -1
  170. package/src/actions/marks/line/actions.js +40 -17
  171. package/src/actions/marks/line/materialize.js +29 -10
  172. package/src/actions/marks/point/create.js +9 -3
  173. package/src/actions/marks/point/edit.js +19 -7
  174. package/src/actions/marks/point/jitter.js +6 -8
  175. package/src/actions/marks/point/materialize.js +48 -22
  176. package/src/actions/marks/point/packing.js +6 -8
  177. package/src/actions/marks/rect/actions.js +36 -15
  178. package/src/actions/marks/references.js +602 -33
  179. package/src/actions/marks/remove.js +67 -41
  180. package/src/actions/marks/rule/actions.js +51 -14
  181. package/src/actions/marks/shared.js +1 -1
  182. package/src/actions/marks/text/actions.js +79 -14
  183. package/src/actions/marks/text/index.js +4 -0
  184. package/src/actions/marks/text/layout.js +157 -17
  185. package/src/actions/marks/text/removal.js +173 -0
  186. package/src/actions/marks/text/selection.js +72 -0
  187. package/src/actions/marks/tick/actions.js +25 -8
  188. package/src/actions/primitives/createGraphics.js +5 -4
  189. package/src/actions/primitives/editGraphics.js +31 -4
  190. package/src/actions/primitives/graphicProperties.js +6 -0
  191. package/src/actions/primitives/semantic.js +11 -3
  192. package/src/actions/primitives/semanticAction.js +90 -14
  193. package/src/actions/primitives/semanticValidation/dataset.js +2 -4
  194. package/src/actions/primitives/semanticValidation/guide.js +1 -1
  195. package/src/actions/primitives/semanticValidation/index.js +9 -1
  196. package/src/actions/primitives/semanticValidation/layer.js +5 -0
  197. package/src/actions/primitives/semanticValidation/scale.js +28 -7
  198. package/src/actions/regression/components.js +36 -25
  199. package/src/actions/regression/create.js +13 -6
  200. package/src/actions/regression/edit.js +24 -11
  201. package/src/actions/resources/index.js +7 -0
  202. package/src/actions/resources/remove.js +173 -0
  203. package/src/actions/scales/channels.js +212 -0
  204. package/src/actions/scales/consumers/common.js +1 -1
  205. package/src/actions/scales/consumers/families.js +3 -2
  206. package/src/actions/scales/consumers/index.js +19 -2
  207. package/src/actions/scales/consumers/seriesLayout.js +28 -14
  208. package/src/actions/scales/create.js +55 -23
  209. package/src/actions/scales/definitions.js +94 -40
  210. package/src/actions/scales/edit.js +67 -12
  211. package/src/actions/scales/editPolicy.js +81 -11
  212. package/src/actions/scales/index.js +6 -0
  213. package/src/actions/scales/materialize.js +5 -4
  214. package/src/actions/scales/offset.js +48 -0
  215. package/src/actions/scales/parallel.js +71 -0
  216. package/src/actions/scales/preview.js +111 -10
  217. package/src/actions/scales/quantitativeColor.js +4 -5
  218. package/src/actions/selection/actions.js +179 -66
  219. package/src/actions/selection/index.js +3 -0
  220. package/src/actions/textMetrics/index.js +56 -0
  221. package/src/actions/theme/actions.js +70 -15
  222. package/src/actions/theme/composition.js +238 -0
  223. package/src/actions/theme/index.js +9 -2
  224. package/src/actions/theme/reconcile.js +313 -121
  225. package/src/actions/theme/state.js +160 -0
  226. package/src/actions/titles/actions.js +8 -8
  227. package/src/actions/titles/resolve.js +3 -3
  228. package/src/actions/violinPlots/create.js +6 -3
  229. package/src/actions/violinPlots/edit.js +2 -1
  230. package/src/core/action.js +117 -35
  231. package/src/core/compositionState.js +6 -1
  232. package/src/core/diagnostics.js +16 -0
  233. package/src/core/extensionRegistry.js +27 -0
  234. package/src/core/font.js +18 -0
  235. package/src/core/identifiers.js +5 -4
  236. package/src/core/immutable.js +10 -3
  237. package/src/core/optionRequirements.js +8 -0
  238. package/src/core/programState.js +21 -1
  239. package/src/core/resourceReferences.js +341 -0
  240. package/src/core/textMetricProfile.js +28 -0
  241. package/src/core/textMetrics.js +24 -3
  242. package/src/core/validation.js +22 -10
  243. package/src/core/vocabulary.js +16 -3
  244. package/src/diagnostics.js +1 -0
  245. package/src/grammar/bars/aggregate.js +4 -1
  246. package/src/grammar/bars/geometry.js +44 -0
  247. package/src/grammar/bin.js +54 -9
  248. package/src/grammar/complete.js +279 -0
  249. package/src/grammar/computed.js +265 -64
  250. package/src/grammar/coordinates.js +37 -0
  251. package/src/grammar/density.js +239 -37
  252. package/src/grammar/displayLabels.js +57 -0
  253. package/src/grammar/facets/dependencies.js +133 -1
  254. package/src/grammar/facets/guides.js +3 -0
  255. package/src/grammar/facets/index.js +7 -47
  256. package/src/grammar/facets/scales.js +15 -18
  257. package/src/grammar/impute.js +341 -0
  258. package/src/grammar/markLabelSelection.js +57 -0
  259. package/src/grammar/markLabels.js +18 -1
  260. package/src/grammar/normalize.js +366 -0
  261. package/src/grammar/pathSeries.js +26 -8
  262. package/src/grammar/pointShapes.js +13 -4
  263. package/src/grammar/polar.js +90 -8
  264. package/src/grammar/regression/index.js +1 -0
  265. package/src/grammar/regression/parameters.js +23 -0
  266. package/src/grammar/roundedRect.js +180 -0
  267. package/src/grammar/rules.js +1 -0
  268. package/src/grammar/scales/colorConsumers.js +20 -1
  269. package/src/grammar/scales/continuous.js +2 -2
  270. package/src/grammar/scales/definition.js +27 -4
  271. package/src/grammar/scales/index.js +1 -0
  272. package/src/grammar/scales/ordinal.js +12 -3
  273. package/src/grammar/scales/policies.js +2 -2
  274. package/src/grammar/scales/size.js +456 -0
  275. package/src/grammar/scales/types.js +8 -0
  276. package/src/grammar/schemas/concreteGraphic.js +14 -2
  277. package/src/grammar/schemas/graphic.js +15 -0
  278. package/src/grammar/schemas/graphicBounds.js +190 -41
  279. package/src/grammar/schemas/semanticPath.js +7 -2
  280. package/src/grammar/statisticalReference.js +103 -0
  281. package/src/grammar/strokeStyle.js +77 -0
  282. package/src/grammar/summary.js +78 -16
  283. package/src/grammar/timeUnit.js +216 -5
  284. package/src/grammar/transformTopology.js +4 -0
  285. package/src/grammar/transforms.js +394 -28
  286. package/src/grammar/weightedStatistics.js +374 -0
  287. package/src/grammar/window.js +221 -16
  288. package/src/layout/aspect.js +80 -0
  289. package/src/layout/facets.js +59 -5
  290. package/src/layout/labels.js +351 -7
  291. package/src/layout/legend.js +4 -4
  292. package/src/layout/legendItems.js +6 -6
  293. package/src/layout/text.js +10 -9
  294. package/src/layout/title.js +9 -9
  295. package/src/materialization/bars/aggregate.js +25 -2
  296. package/src/materialization/bars/histogram.js +84 -24
  297. package/src/materialization/bars/ranged.js +19 -3
  298. package/src/materialization/bars/resolve.js +7 -4
  299. package/src/materialization/composition.js +3 -1
  300. package/src/materialization/coordinateBounds.js +204 -0
  301. package/src/materialization/dependencies.js +36 -0
  302. package/src/materialization/facetGuides/legacyCategorical.js +3 -0
  303. package/src/materialization/facetGuides/placement.js +9 -3
  304. package/src/materialization/facetGuides/preparation.js +13 -8
  305. package/src/materialization/facetHeaders.js +347 -0
  306. package/src/materialization/facets.js +15 -65
  307. package/src/materialization/guides/layout.js +3 -3
  308. package/src/materialization/guides/resources.js +26 -0
  309. package/src/materialization/legends.js +1 -1
  310. package/src/materialization/marks/index.js +11 -5
  311. package/src/materialization/marks/policies.js +2 -1
  312. package/src/materialization/rect.js +25 -12
  313. package/src/materialization/rectConfig.js +5 -1
  314. package/src/materialization/scaleGuideDependencies.js +10 -0
  315. package/src/materialization/scales/map.js +5 -3
  316. package/src/materialization/scales/policies/binnedPosition.js +2 -2
  317. package/src/materialization/scales/policies/offset.js +50 -8
  318. package/src/materialization/scales/policies/series.js +4 -1
  319. package/src/materialization/scales/resolve.js +22 -6
  320. package/src/materialization/selection/items/arc.js +28 -4
  321. package/src/materialization/selection/items/bar.js +30 -3
  322. package/src/materialization/selection/items/common.js +20 -5
  323. package/src/materialization/selection/items/rect.js +28 -4
  324. package/src/materialization/selection/path.js +1 -1
  325. package/src/materialization/selection/point.js +3 -1
  326. package/src/materialization/text.js +265 -14
  327. package/src/materialization/typography.js +31 -0
  328. package/src/mcp/cli.js +5 -3
  329. package/src/persistence/codec.js +65 -0
  330. package/src/persistence/validation.js +185 -0
  331. package/src/persistence.js +74 -0
  332. package/src/renderers/canvas/circle.js +2 -3
  333. package/src/renderers/canvas/index.js +5 -4
  334. package/src/renderers/canvas/line.js +2 -3
  335. package/src/renderers/canvas/native.js +4 -4
  336. package/src/renderers/canvas/path.js +2 -3
  337. package/src/renderers/canvas/rect.js +2 -3
  338. package/src/renderers/canvas/stroke.js +11 -0
  339. package/src/renderers/nativeBackend.js +10 -0
  340. package/src/renderers/options.js +13 -0
  341. package/src/renderers/pdf.js +25 -54
  342. package/src/renderers/png.js +22 -17
  343. package/src/renderers/svg.js +29 -14
  344. package/src/renderers/text.js +1 -11
  345. package/src/selectors/coordinates.js +3 -1
  346. package/src/selectors/datasets.js +38 -5
  347. package/src/selectors/layers.js +10 -4
  348. package/src/selectors/markOwners.js +46 -0
  349. package/src/selectors/scales.js +6 -4
  350. package/src/theme/defaults.js +103 -1
  351. package/src/version.js +2 -0
  352. package/types/accessibility.d.ts +37 -0
  353. package/types/basic.d.ts +10 -2
  354. package/types/diagnostics.d.ts +15 -0
  355. package/types/index.d.ts +90 -0
  356. package/types/pdf.d.ts +9 -0
  357. package/types/persistence.d.ts +7 -0
  358. package/types/png.d.ts +9 -0
  359. package/types/program.d.ts +944 -118
@@ -7,10 +7,10 @@ import { derivedCreator, derivedMaterializer } from "./shared.js";
7
7
 
8
8
  const OPTIONS = Object.freeze([
9
9
  "id", "source", "field", "maxBins", "step", "boundaries", "extent",
10
- "nice", "zero", "includeEmpty", "members", "as"
10
+ "nice", "zero", "includeEmpty", "members", "as", "weight"
11
11
  ]);
12
12
 
13
- export const materializeBinData = derivedMaterializer(
13
+ export const materializeBinData = /* @__PURE__ */ derivedMaterializer(
14
14
  "materializeBinData",
15
15
  "Materialize one immutable one-dimensional bin dataset.",
16
16
  "bin",
@@ -18,7 +18,7 @@ export const materializeBinData = derivedMaterializer(
18
18
  resolveBinTransform
19
19
  );
20
20
 
21
- export const createBinData = derivedCreator(
21
+ export const createBinData = /* @__PURE__ */ derivedCreator(
22
22
  "createBinData",
23
23
  "Create reusable one-dimensional bin bounds, counts, and members.",
24
24
  OPTIONS,
@@ -1,29 +1,33 @@
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
  deriveBin2DRows,
6
6
  normalizeBin2DTransform,
7
7
  requestedBin2DTransform
8
8
  } from "../../grammar/bin2d.js";
9
- import { applyLayerDataRematerialization } from
10
- "../../materialization/dependencies.js";
11
- import { planDerivedDataRevision } from
12
- "../../materialization/dataProvenance.js";
13
9
  import {
14
10
  findDataset,
15
- findDatasetConsumer
11
+ resolveDatasetReference
16
12
  } from "../../selectors/datasets.js";
17
- import { requireLayer } from "../../selectors/layers.js";
13
+ import {
14
+ normalizeDerivedDependentPolicy,
15
+ resolveDerivedDataOwner,
16
+ reviseDerivedData
17
+ } from "./edit.js";
18
+ import { normalizeDatasetTransformEdit } from "../../grammar/transforms.js";
18
19
  export { materializeBin2DData } from "./bin2dMaterialize.js";
19
20
 
20
21
  const OPTIONS = Object.freeze([
21
22
  "id", "source", "x", "y", "bins", "extent", "includeEmpty", "members", "as"
22
23
  ]);
23
24
  const EDIT_OPTIONS = Object.freeze([
24
- "target", "source", "x", "y", "bins", "extent", "includeEmpty", "members", "as"
25
+ "target", "source", "x", "y", "bins", "extent", "includeEmpty",
26
+ "members", "as", "dependents"
25
27
  ]);
26
- const EDITABLE = Object.freeze(EDIT_OPTIONS.slice(1));
28
+ const EDITABLE = Object.freeze(EDIT_OPTIONS.filter(option =>
29
+ !["target", "dependents"].includes(option)
30
+ ));
27
31
  const OUTPUT_FIELDS = Object.freeze([
28
32
  "x0", "x1", "y0", "y1", "count", "members"
29
33
  ]);
@@ -69,122 +73,6 @@ function requireCurrentBin2D(program, id, config) {
69
73
  return current;
70
74
  }
71
75
 
72
- function directLayerConsumers(program, data) {
73
- return program.semanticSpec.layers
74
- .filter(layer => layer.data === data)
75
- .map(layer => layer.id);
76
- }
77
-
78
- function outputFieldChanges(previous, next) {
79
- return new Map(OUTPUT_FIELDS.flatMap(role => {
80
- const from = previous.as[role];
81
- const to = next.as[role];
82
- return from !== undefined && from !== to
83
- ? [[from, [role, to]]]
84
- : [];
85
- }));
86
- }
87
-
88
- function changedConsumerField(field, changes) {
89
- const change = changes.get(field);
90
- if (change === undefined) return field;
91
- const [role, next] = change;
92
- if (next === undefined) {
93
- throw new Error(
94
- `Cannot remove referenced 2D bin ${role} output field "${field}".`
95
- );
96
- }
97
- return next;
98
- }
99
-
100
- function rebindLayerOutputFields(program, id, changes) {
101
- const layer = requireLayer(program, id);
102
- let next = program;
103
- const changed = field => changedConsumerField(field, changes);
104
- const editField = (property, field) => {
105
- if (field === undefined) return;
106
- const value = changed(field);
107
- if (value !== field) next = next.editSemantic({ property, value });
108
- };
109
- for (const [channel, encoding] of Object.entries(layer.encoding ?? {})) {
110
- editField(
111
- `layer[${id}].encoding.${channel}.field`,
112
- encoding?.field
113
- );
114
- const summary = encoding?.categoryOrder?.by;
115
- if (summary?.field !== undefined) {
116
- const field = changed(summary.field);
117
- if (field !== summary.field) {
118
- next = next.editSemantic({
119
- property: `layer[${id}].encoding.${channel}.categoryOrder`,
120
- value: { ...encoding.categoryOrder, by: { ...summary, field } }
121
- });
122
- }
123
- }
124
- }
125
- editField(
126
- `layer[${id}].encoding.theta.weight`,
127
- layer.encoding?.theta?.weight
128
- );
129
-
130
- const parallel = layer.encoding?.parallel;
131
- if (parallel?.dimensions !== undefined) {
132
- const dimensions = parallel.dimensions.map(dimension => {
133
- const field = changed(dimension.field);
134
- return { ...dimension, field };
135
- });
136
- if (dimensions.some((dimension, index) =>
137
- dimension.field !== parallel.dimensions[index].field
138
- )) {
139
- next = next.editSemantic({
140
- property: `layer[${id}].encoding.parallel.dimensions`,
141
- value: dimensions
142
- });
143
- }
144
- }
145
- editField(
146
- `layer[${id}].encoding.parallel.key`,
147
- parallel?.key
148
- );
149
-
150
- for (const [selectionId, config] of Object.entries(
151
- program.materializationConfigs.selections ?? {}
152
- )) {
153
- if (config.target !== id) continue;
154
- const selector = { ...config.selector };
155
- if (selector.field !== undefined) {
156
- selector.field = changed(selector.field);
157
- }
158
- if (selector.groupBy !== undefined) {
159
- selector.groupBy = selector.groupBy.map(changed);
160
- }
161
- if (JSON.stringify(selector) !== JSON.stringify(config.selector)) {
162
- next = next._withSelectionConfig(selectionId, { ...config, selector });
163
- }
164
- }
165
-
166
- const jitter = program.materializationConfigs.jitters?.[id];
167
- const key = jitter?.key === undefined
168
- ? undefined
169
- : changed(jitter.key);
170
- if (key !== undefined && key !== jitter.key) {
171
- next = next._withMaterializationConfig(
172
- ["jitters", id], { ...jitter, key }
173
- );
174
- }
175
- return next;
176
- }
177
-
178
- function rejectDerivedConsumers(program, data) {
179
- const dependent = findDatasetConsumer(program, data);
180
- if (dependent !== undefined) {
181
- throw new Error(
182
- `Cannot replace 2D bin dataset "${data}" while derived dataset ` +
183
- `"${dependent.id}" depends on it.`
184
- );
185
- }
186
- }
187
-
188
76
  function preflight(program, sourceId, transform) {
189
77
  const source = findDataset(program, sourceId);
190
78
  if (source?.values === undefined) {
@@ -204,32 +92,18 @@ function requireCompleteEditOutputFields(value, members) {
204
92
  }
205
93
 
206
94
  function editedTransform(owner, previous, args) {
207
- const prior = requestedBin2DTransform(previous.transform[0]);
208
- const option = property => Object.hasOwn(args, property)
209
- ? args[property]
210
- : prior[property];
211
- const members = option("members");
212
- let as = option("as");
213
- if (!Object.hasOwn(args, "as")) {
214
- as = { ...as };
215
- if (members && as.members === undefined) {
216
- as.members = `__${owner}_members`;
217
- } else if (!members) {
218
- delete as.members;
219
- }
220
- }
221
- const transform = normalizeBin2DTransform({
222
- id: owner,
223
- x: option("x"),
224
- y: option("y"),
225
- bins: option("bins"),
226
- extent: option("extent"),
227
- includeEmpty: option("includeEmpty"),
228
- members,
229
- as
230
- });
95
+ const patch = Object.fromEntries(EDITABLE.flatMap(property =>
96
+ property !== "source" && Object.hasOwn(args, property)
97
+ ? [[property, args[property]]]
98
+ : []
99
+ ));
100
+ const transform = normalizeDatasetTransformEdit(
101
+ previous.transform[0],
102
+ patch,
103
+ owner
104
+ );
231
105
  if (Object.hasOwn(args, "as")) {
232
- requireCompleteEditOutputFields(args.as, members);
106
+ requireCompleteEditOutputFields(args.as, transform.members);
233
107
  }
234
108
  return transform;
235
109
  }
@@ -238,47 +112,39 @@ function sameRequestedTransform(left, right) {
238
112
  return JSON.stringify(left) === JSON.stringify(right);
239
113
  }
240
114
 
241
- function applyBin2DRevision(program, { owner, previous, source, transform }) {
242
- rejectDerivedConsumers(program, previous.id);
243
- const consumers = directLayerConsumers(program, previous.id);
244
- const changes = outputFieldChanges(previous.transform[0], transform);
245
- const revision = planDerivedDataRevision(program, {
246
- owner,
247
- role: "Bin2DData",
248
- previous: previous.id,
249
- consumers
115
+ function applyBin2DRevision(program, {
116
+ owner,
117
+ source,
118
+ transform,
119
+ dependents = "reject"
120
+ }) {
121
+ return reviseDerivedData(program, {
122
+ resolved: resolveDerivedDataOwner(program, owner, "bin2d"),
123
+ definition: transform,
124
+ dependents,
125
+ source
250
126
  });
251
- let next = program
252
- .createDerivedData({ id: revision.id, source, transform: [transform] })
253
- .materializeBin2DData({ id: revision.id });
254
- for (const rebind of revision.rebinds) {
255
- next = next.rebindLayerData(rebind);
256
- next = rebindLayerOutputFields(next, rebind.id, changes);
257
- next = applyLayerDataRematerialization(next, rebind.id);
258
- }
259
- next = next.releaseDerivedData(revision.release);
260
- return next._withMaterializationConfig(
261
- ["data", "bin2d", owner],
262
- { current: revision.id }
263
- );
264
127
  }
265
128
 
266
- export const createBin2DData = action(
129
+ export const createBin2DData = /* @__PURE__ */ closedAction(
267
130
  {
268
131
  op: "createBin2DData",
269
132
  description: "Create or revise immutable rectangular 2D-bin values."
270
- },
133
+ }, OPTIONS,
271
134
  function (args = {}) {
272
- validateKeys(args, OPTIONS, "createBin2DData");
273
135
  const owner = validateUserId(args.id, "2D bin dataset id");
274
136
  const config = ownerConfig(this, owner);
275
137
  const previous = config === undefined
276
138
  ? undefined
277
139
  : requireCurrentBin2D(this, owner, config);
278
- const source = validateUserId(
279
- args.source ?? previous?.source ?? this.context.currentData,
280
- "Source dataset id"
281
- );
140
+ const source = resolveDatasetReference(
141
+ this,
142
+ validateUserId(
143
+ args.source ?? previous?.source ?? this.context.currentData,
144
+ "Source dataset id"
145
+ ),
146
+ "Source dataset"
147
+ ).id;
282
148
  const transform = normalizeBin2DTransform({ ...args, id: owner });
283
149
  preflight(this, source, transform);
284
150
 
@@ -301,22 +167,26 @@ export const createBin2DData = action(
301
167
  }
302
168
  );
303
169
 
304
- export const editBin2DData = action(
170
+ export const editBin2DData = /* @__PURE__ */ closedAction(
305
171
  {
306
172
  op: "editBin2DData",
307
173
  description: "Partially revise one logical rectangular 2D-bin owner."
308
- },
174
+ }, EDIT_OPTIONS,
309
175
  function (args = {}) {
310
- validateKeys(args, EDIT_OPTIONS, "editBin2DData");
311
176
  if (!EDITABLE.some(option => Object.hasOwn(args, option))) {
312
177
  throw new Error("editBin2DData requires at least one transform or source option.");
313
178
  }
314
179
  const owner = resolveBin2DOwner(this, args.target);
315
180
  const previous = requireCurrentBin2D(this, owner, ownerConfig(this, owner));
316
- const source = validateUserId(
317
- args.source ?? previous.source,
318
- "2D bin source dataset id"
319
- );
181
+ const dependents = normalizeDerivedDependentPolicy(args.dependents);
182
+ const source = resolveDatasetReference(
183
+ this,
184
+ validateUserId(
185
+ args.source ?? previous.source,
186
+ "2D bin source dataset id"
187
+ ),
188
+ "2D bin source dataset"
189
+ ).id;
320
190
  const transform = editedTransform(owner, previous, args);
321
191
  if (
322
192
  source === previous.source &&
@@ -328,11 +198,11 @@ export const editBin2DData = action(
328
198
  throw new Error("editBin2DData requires an actual transform or source change.");
329
199
  }
330
200
  preflight(this, source, transform);
331
- const revision = { owner, previous, source, transform };
332
-
333
- // Execute one speculative immutable branch so every consumer plan is known
334
- // to succeed before the returned action trace records its first child.
335
- applyBin2DRevision(this, revision);
336
- return applyBin2DRevision(this, revision);
201
+ return applyBin2DRevision(this, {
202
+ owner,
203
+ source,
204
+ transform,
205
+ dependents
206
+ });
337
207
  }
338
208
  );
@@ -1,15 +1,14 @@
1
- import { action } from "../../core/action.js";
2
- import { validateKeys } from "../../core/validation.js";
1
+ import { closedAction } from "../../core/action.js";
2
+
3
3
  import { deriveBin2DRows } from "../../grammar/bin2d.js";
4
4
  import { MATERIALIZE_OPTIONS, requireDerivedDataset } from "./shared.js";
5
5
 
6
- export const materializeBin2DData = action(
6
+ export const materializeBin2DData = /* @__PURE__ */ closedAction(
7
7
  {
8
8
  op: "materializeBin2DData",
9
9
  description: "Materialize one immutable rectangular 2D-bin dataset."
10
- },
10
+ }, MATERIALIZE_OPTIONS,
11
11
  function (args = {}) {
12
- validateKeys(args, MATERIALIZE_OPTIONS, "materializeBin2DData");
13
12
  const { id, source, transform } = requireDerivedDataset(
14
13
  this,
15
14
  args.id,
@@ -14,8 +14,8 @@ function materializer(type, op, select) {
14
14
  );
15
15
  }
16
16
 
17
- export const materializeBoxSummaryData = materializer("boxSummary", "materializeBoxSummaryData", value => value.summaries);
18
- export const materializeBoxOutlierData = materializer("boxOutlier", "materializeBoxOutlierData", value => value.outliers);
17
+ export const materializeBoxSummaryData = /* @__PURE__ */ materializer("boxSummary", "materializeBoxSummaryData", value => value.summaries);
18
+ export const materializeBoxOutlierData = /* @__PURE__ */ materializer("boxOutlier", "materializeBoxOutlierData", value => value.outliers);
19
19
 
20
20
  function creator(type, op, materialize) {
21
21
  return derivedCreator(
@@ -36,5 +36,5 @@ function creator(type, op, materialize) {
36
36
  );
37
37
  }
38
38
 
39
- export const createBoxSummaryData = creator("boxSummary", "createBoxSummaryData", "materializeBoxSummaryData");
40
- export const createBoxOutlierData = creator("boxOutlier", "createBoxOutlierData", "materializeBoxOutlierData");
39
+ export const createBoxSummaryData = /* @__PURE__ */ creator("boxSummary", "createBoxSummaryData", "materializeBoxSummaryData");
40
+ export const createBoxOutlierData = /* @__PURE__ */ creator("boxOutlier", "createBoxOutlierData", "materializeBoxOutlierData");
@@ -0,0 +1,26 @@
1
+ import {
2
+ deriveCompleteRows,
3
+ normalizeCompleteTransform
4
+ } from "../../grammar/complete.js";
5
+ import { derivedCreator, derivedMaterializer } from "./shared.js";
6
+
7
+ const OPTIONS = Object.freeze([
8
+ "id", "source", "key", "groupBy", "values", "sequence", "fill", "members"
9
+ ]);
10
+
11
+ export const materializeCompleteData = /* @__PURE__ */ derivedMaterializer(
12
+ "materializeCompleteData",
13
+ "Materialize one immutable completed-key dataset.",
14
+ "complete",
15
+ deriveCompleteRows
16
+ );
17
+
18
+ export const createCompleteData = /* @__PURE__ */ derivedCreator(
19
+ "createCompleteData",
20
+ "Complete one key domain independently within observed groups.",
21
+ OPTIONS,
22
+ "Complete dataset id",
23
+ "Complete source dataset id",
24
+ normalizeCompleteTransform,
25
+ "materializeCompleteData"
26
+ );
@@ -6,16 +6,16 @@ import { derivedCreator, derivedMaterializer } from "./shared.js";
6
6
 
7
7
  const OPTIONS = Object.freeze(["id", "source", "as", "expression"]);
8
8
 
9
- export const materializeComputedData = derivedMaterializer(
9
+ export const materializeComputedData = /* @__PURE__ */ derivedMaterializer(
10
10
  "materializeComputedData",
11
- "Materialize one immutable row-level arithmetic dataset.",
11
+ "Materialize one immutable row-level typed expression dataset.",
12
12
  "computed",
13
13
  deriveComputedRows
14
14
  );
15
15
 
16
- export const createComputedData = derivedCreator(
16
+ export const createComputedData = /* @__PURE__ */ derivedCreator(
17
17
  "createComputedData",
18
- "Create a finite computed field from a closed arithmetic expression.",
18
+ "Create a typed computed field from a closed expression.",
19
19
  OPTIONS,
20
20
  "Computed dataset id",
21
21
  "Computed source dataset id",
@@ -1,28 +1,21 @@
1
- import { action } from "../../core/action.js";
1
+ import { closedAction } from "../../core/action.js";
2
2
  import { resolveOptionalUserId } from "../../core/identifiers.js";
3
- import { isPlainObject } from "../../core/immutable.js";
4
- import { validateKeys } from "../../core/validation.js";
5
- import { hasDataset } from "../../selectors/index.js";
3
+ import { validateDataRows } from "../../core/validation.js";
4
+ import { hasDataset, hasDatasetOwner } from "../../selectors/index.js";
6
5
 
7
6
  const OPTIONS = Object.freeze(["id", "values"]);
8
7
 
9
- export const createData = action(
10
- { op: "createData", description: "Create an immutable named dataset." },
8
+ export const createData = /* @__PURE__ */ closedAction(
9
+ { op: "createData", description: "Create an immutable named dataset." }, OPTIONS,
11
10
  function (args = {}) {
12
- validateKeys(args, OPTIONS, "createData");
13
11
  const id = resolveOptionalUserId(args.id, {
14
12
  defaultId: "data",
15
13
  label: "Dataset id",
16
14
  operation: "createData",
17
15
  ambiguous: this.semanticSpec.datasets.length > 0
18
16
  });
19
- if (!Array.isArray(args.values)) {
20
- throw new TypeError("createData requires values to be an array.");
21
- }
22
- if (!args.values.every(isPlainObject)) {
23
- throw new TypeError("createData requires every row to be a plain object.");
24
- }
25
- if (hasDataset(this, id)) {
17
+ validateDataRows(args.values, "createData");
18
+ if (hasDataset(this, id) || hasDatasetOwner(this, id)) {
26
19
  throw new Error(`Dataset "${id}" already exists.`);
27
20
  }
28
21
  return this.editSemantic({
@@ -1,28 +1,15 @@
1
- import { deriveKernelDensity } from "../../grammar/density.js";
1
+ import {
2
+ deriveKernelDensity,
3
+ normalizeDensityTransform
4
+ } from "../../grammar/density.js";
2
5
  import { derivedCreator, derivedMaterializer } from "./shared.js";
3
6
 
4
7
  const OPTIONS = Object.freeze([
5
8
  "id", "source", "field", "groupBy", "bandwidth", "extent", "steps",
6
- "kernel", "normalization", "as"
9
+ "kernel", "normalization", "as", "weight"
7
10
  ]);
8
11
  const CATEGORICAL_OPTIONS = Object.freeze([...OPTIONS, "placement"]);
9
12
 
10
- function densityTransform(args, placement) {
11
- return {
12
- type: "density",
13
- field: args.field,
14
- ...(args.groupBy === undefined ? {} : { groupBy: args.groupBy }),
15
- bandwidth: args.bandwidth ?? "auto",
16
- extent: args.extent ?? "auto",
17
- steps: args.steps ?? 100,
18
- kernel: args.kernel ?? "gaussian",
19
- normalization: args.normalization ?? "unit",
20
- as: args.as ?? [`${args.field}_value`, `${args.field}_density`],
21
- resolve: "shared",
22
- ...(placement === undefined ? {} : { placement })
23
- };
24
- }
25
-
26
13
  function requestedTransform(args, op, categorical = false) {
27
14
  if (typeof args.field !== "string" || args.field.length === 0) {
28
15
  throw new TypeError(`${op} requires a non-empty field string.`);
@@ -32,10 +19,13 @@ function requestedTransform(args, op, categorical = false) {
32
19
  "createCategoricalDensityData requires normalized category placement."
33
20
  );
34
21
  }
35
- return densityTransform(args, categorical ? args.placement : undefined);
22
+ return normalizeDensityTransform({
23
+ ...args,
24
+ ...(categorical ? { placement: args.placement } : {})
25
+ });
36
26
  }
37
27
 
38
- export const materializeDensityData = derivedMaterializer(
28
+ export const materializeDensityData = /* @__PURE__ */ derivedMaterializer(
39
29
  "materializeDensityData",
40
30
  "Materialize one grouped kernel-density dataset.",
41
31
  "density",
@@ -43,7 +33,9 @@ export const materializeDensityData = derivedMaterializer(
43
33
  (result, transform) => [{
44
34
  ...transform,
45
35
  resolved: {
46
- bandwidth: result.bandwidth,
36
+ ...(result.bandwidth === undefined
37
+ ? { bandwidths: result.bandwidths }
38
+ : { bandwidth: result.bandwidth }),
47
39
  extent: result.extent,
48
40
  ...(result.splitDomain === undefined
49
41
  ? {}
@@ -52,7 +44,7 @@ export const materializeDensityData = derivedMaterializer(
52
44
  }]
53
45
  );
54
46
 
55
- export const createDensityData = derivedCreator(
47
+ export const createDensityData = /* @__PURE__ */ derivedCreator(
56
48
  "createDensityData",
57
49
  "Create grouped kernel-density values.",
58
50
  OPTIONS,
@@ -62,7 +54,7 @@ export const createDensityData = derivedCreator(
62
54
  "materializeDensityData"
63
55
  );
64
56
 
65
- export const createCategoricalDensityData = derivedCreator(
57
+ export const createCategoricalDensityData = /* @__PURE__ */ derivedCreator(
66
58
  "createCategoricalDensityData",
67
59
  "Create category-placed kernel-density values.",
68
60
  CATEGORICAL_OPTIONS,