@ggts-sh/spec 0.43.0

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 (679) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +75 -0
  3. package/dist/artifact.d.ts +11 -0
  4. package/dist/artifact.d.ts.map +1 -0
  5. package/dist/artifact.js +71 -0
  6. package/dist/artifact.js.map +1 -0
  7. package/dist/builder-core.d.ts +100 -0
  8. package/dist/builder-core.d.ts.map +1 -0
  9. package/dist/builder-core.js +176 -0
  10. package/dist/builder-core.js.map +1 -0
  11. package/dist/builder-data.d.ts +36 -0
  12. package/dist/builder-data.d.ts.map +1 -0
  13. package/dist/builder-data.js +123 -0
  14. package/dist/builder-data.js.map +1 -0
  15. package/dist/builder-geoms.d.ts +128 -0
  16. package/dist/builder-geoms.d.ts.map +1 -0
  17. package/dist/builder-geoms.js +221 -0
  18. package/dist/builder-geoms.js.map +1 -0
  19. package/dist/builder-options.d.ts +323 -0
  20. package/dist/builder-options.d.ts.map +1 -0
  21. package/dist/builder-options.js +2 -0
  22. package/dist/builder-options.js.map +1 -0
  23. package/dist/builder-scales.d.ts +160 -0
  24. package/dist/builder-scales.d.ts.map +1 -0
  25. package/dist/builder-scales.js +322 -0
  26. package/dist/builder-scales.js.map +1 -0
  27. package/dist/builder.d.ts +242 -0
  28. package/dist/builder.d.ts.map +1 -0
  29. package/dist/builder.js +42 -0
  30. package/dist/builder.js.map +1 -0
  31. package/dist/capabilities-data.d.ts +72 -0
  32. package/dist/capabilities-data.d.ts.map +1 -0
  33. package/dist/capabilities-data.js +337 -0
  34. package/dist/capabilities-data.js.map +1 -0
  35. package/dist/capabilities-helpers.d.ts +31 -0
  36. package/dist/capabilities-helpers.d.ts.map +1 -0
  37. package/dist/capabilities-helpers.js +41 -0
  38. package/dist/capabilities-helpers.js.map +1 -0
  39. package/dist/capabilities.d.ts +22 -0
  40. package/dist/capabilities.d.ts.map +1 -0
  41. package/dist/capabilities.js +154 -0
  42. package/dist/capabilities.js.map +1 -0
  43. package/dist/coord-helpers.d.ts +102 -0
  44. package/dist/coord-helpers.d.ts.map +1 -0
  45. package/dist/coord-helpers.js +90 -0
  46. package/dist/coord-helpers.js.map +1 -0
  47. package/dist/coord-reference-build.d.ts +50 -0
  48. package/dist/coord-reference-build.d.ts.map +1 -0
  49. package/dist/coord-reference-build.js +211 -0
  50. package/dist/coord-reference-build.js.map +1 -0
  51. package/dist/coord-reference.d.ts +52 -0
  52. package/dist/coord-reference.d.ts.map +1 -0
  53. package/dist/coord-reference.js +27 -0
  54. package/dist/coord-reference.js.map +1 -0
  55. package/dist/error-catalog.d.ts +258 -0
  56. package/dist/error-catalog.d.ts.map +1 -0
  57. package/dist/error-catalog.js +235 -0
  58. package/dist/error-catalog.js.map +1 -0
  59. package/dist/error-prose-shared.d.ts +100 -0
  60. package/dist/error-prose-shared.d.ts.map +1 -0
  61. package/dist/error-prose-shared.js +95 -0
  62. package/dist/error-prose-shared.js.map +1 -0
  63. package/dist/errors.d.ts +39 -0
  64. package/dist/errors.d.ts.map +1 -0
  65. package/dist/errors.js +52 -0
  66. package/dist/errors.js.map +1 -0
  67. package/dist/generated/coord-reference-data.d.ts +189 -0
  68. package/dist/generated/coord-reference-data.d.ts.map +1 -0
  69. package/dist/generated/coord-reference-data.js +212 -0
  70. package/dist/generated/coord-reference-data.js.map +1 -0
  71. package/dist/generated/geom-param-keys.d.ts +58 -0
  72. package/dist/generated/geom-param-keys.d.ts.map +1 -0
  73. package/dist/generated/geom-param-keys.js +223 -0
  74. package/dist/generated/geom-param-keys.js.map +1 -0
  75. package/dist/generated/geom-reference-data.d.ts +2377 -0
  76. package/dist/generated/geom-reference-data.d.ts.map +1 -0
  77. package/dist/generated/geom-reference-data.js +2790 -0
  78. package/dist/generated/geom-reference-data.js.map +1 -0
  79. package/dist/generated/guide-reference-data.d.ts +219 -0
  80. package/dist/generated/guide-reference-data.d.ts.map +1 -0
  81. package/dist/generated/guide-reference-data.js +253 -0
  82. package/dist/generated/guide-reference-data.js.map +1 -0
  83. package/dist/generated/plot-spec-validator.d.ts +2 -0
  84. package/dist/generated/plot-spec-validator.d.ts.map +1 -0
  85. package/dist/generated/plot-spec-validator.js +6274 -0
  86. package/dist/generated/plot-spec-validator.js.map +1 -0
  87. package/dist/generated/position-reference-data.d.ts +82 -0
  88. package/dist/generated/position-reference-data.d.ts.map +1 -0
  89. package/dist/generated/position-reference-data.js +181 -0
  90. package/dist/generated/position-reference-data.js.map +1 -0
  91. package/dist/generated/scale-reference-data.d.ts +8366 -0
  92. package/dist/generated/scale-reference-data.d.ts.map +1 -0
  93. package/dist/generated/scale-reference-data.js +9821 -0
  94. package/dist/generated/scale-reference-data.js.map +1 -0
  95. package/dist/generated/stat-reference-data.d.ts +241 -0
  96. package/dist/generated/stat-reference-data.d.ts.map +1 -0
  97. package/dist/generated/stat-reference-data.js +311 -0
  98. package/dist/generated/stat-reference-data.js.map +1 -0
  99. package/dist/geom-params-build.d.ts +3 -0
  100. package/dist/geom-params-build.d.ts.map +1 -0
  101. package/dist/geom-params-build.js +80 -0
  102. package/dist/geom-params-build.js.map +1 -0
  103. package/dist/geom-params.d.ts +13 -0
  104. package/dist/geom-params.d.ts.map +1 -0
  105. package/dist/geom-params.js +7 -0
  106. package/dist/geom-params.js.map +1 -0
  107. package/dist/geom-reference-build.d.ts +29 -0
  108. package/dist/geom-reference-build.d.ts.map +1 -0
  109. package/dist/geom-reference-build.js +221 -0
  110. package/dist/geom-reference-build.js.map +1 -0
  111. package/dist/geom-reference.d.ts +52 -0
  112. package/dist/geom-reference.d.ts.map +1 -0
  113. package/dist/geom-reference.js +72 -0
  114. package/dist/geom-reference.js.map +1 -0
  115. package/dist/guide-helpers.d.ts +20 -0
  116. package/dist/guide-helpers.d.ts.map +1 -0
  117. package/dist/guide-helpers.js +25 -0
  118. package/dist/guide-helpers.js.map +1 -0
  119. package/dist/guide-reference-build.d.ts +42 -0
  120. package/dist/guide-reference-build.d.ts.map +1 -0
  121. package/dist/guide-reference-build.js +180 -0
  122. package/dist/guide-reference-build.js.map +1 -0
  123. package/dist/guide-reference.d.ts +48 -0
  124. package/dist/guide-reference.d.ts.map +1 -0
  125. package/dist/guide-reference.js +32 -0
  126. package/dist/guide-reference.js.map +1 -0
  127. package/dist/hue-grey-palettes.d.ts +15 -0
  128. package/dist/hue-grey-palettes.d.ts.map +1 -0
  129. package/dist/hue-grey-palettes.js +77 -0
  130. package/dist/hue-grey-palettes.js.map +1 -0
  131. package/dist/index.d.ts +364 -0
  132. package/dist/index.d.ts.map +1 -0
  133. package/dist/index.js +225 -0
  134. package/dist/index.js.map +1 -0
  135. package/dist/lint-catalog.d.ts +47 -0
  136. package/dist/lint-catalog.d.ts.map +1 -0
  137. package/dist/lint-catalog.js +39 -0
  138. package/dist/lint-catalog.js.map +1 -0
  139. package/dist/lint-layer-rules.d.ts +18 -0
  140. package/dist/lint-layer-rules.d.ts.map +1 -0
  141. package/dist/lint-layer-rules.js +145 -0
  142. package/dist/lint-layer-rules.js.map +1 -0
  143. package/dist/lint-scale-rules.d.ts +8 -0
  144. package/dist/lint-scale-rules.d.ts.map +1 -0
  145. package/dist/lint-scale-rules.js +254 -0
  146. package/dist/lint-scale-rules.js.map +1 -0
  147. package/dist/lint.d.ts +62 -0
  148. package/dist/lint.d.ts.map +1 -0
  149. package/dist/lint.js +57 -0
  150. package/dist/lint.js.map +1 -0
  151. package/dist/normalize-coord.d.ts +8 -0
  152. package/dist/normalize-coord.d.ts.map +1 -0
  153. package/dist/normalize-coord.js +123 -0
  154. package/dist/normalize-coord.js.map +1 -0
  155. package/dist/normalize-input-layers-marks.d.ts +208 -0
  156. package/dist/normalize-input-layers-marks.d.ts.map +1 -0
  157. package/dist/normalize-input-layers-marks.js +2 -0
  158. package/dist/normalize-input-layers-marks.js.map +1 -0
  159. package/dist/normalize-input-layers-special.d.ts +131 -0
  160. package/dist/normalize-input-layers-special.d.ts.map +1 -0
  161. package/dist/normalize-input-layers-special.js +2 -0
  162. package/dist/normalize-input-layers-special.js.map +1 -0
  163. package/dist/normalize-input.d.ts +81 -0
  164. package/dist/normalize-input.d.ts.map +1 -0
  165. package/dist/normalize-input.js +2 -0
  166. package/dist/normalize-input.js.map +1 -0
  167. package/dist/normalize-paint.d.ts +8 -0
  168. package/dist/normalize-paint.d.ts.map +1 -0
  169. package/dist/normalize-paint.js +83 -0
  170. package/dist/normalize-paint.js.map +1 -0
  171. package/dist/normalize-scales.d.ts +7 -0
  172. package/dist/normalize-scales.d.ts.map +1 -0
  173. package/dist/normalize-scales.js +90 -0
  174. package/dist/normalize-scales.js.map +1 -0
  175. package/dist/normalize.d.ts +46 -0
  176. package/dist/normalize.d.ts.map +1 -0
  177. package/dist/normalize.js +279 -0
  178. package/dist/normalize.js.map +1 -0
  179. package/dist/paint-helpers.d.ts +45 -0
  180. package/dist/paint-helpers.d.ts.map +1 -0
  181. package/dist/paint-helpers.js +48 -0
  182. package/dist/paint-helpers.js.map +1 -0
  183. package/dist/pipeline-error-catalog.d.ts +319 -0
  184. package/dist/pipeline-error-catalog.d.ts.map +1 -0
  185. package/dist/pipeline-error-catalog.js +260 -0
  186. package/dist/pipeline-error-catalog.js.map +1 -0
  187. package/dist/portability-check.d.ts +35 -0
  188. package/dist/portability-check.d.ts.map +1 -0
  189. package/dist/portability-check.js +121 -0
  190. package/dist/portability-check.js.map +1 -0
  191. package/dist/portability-lossy.d.ts +19 -0
  192. package/dist/portability-lossy.d.ts.map +1 -0
  193. package/dist/portability-lossy.js +65 -0
  194. package/dist/portability-lossy.js.map +1 -0
  195. package/dist/portability.d.ts +23 -0
  196. package/dist/portability.d.ts.map +1 -0
  197. package/dist/portability.js +23 -0
  198. package/dist/portability.js.map +1 -0
  199. package/dist/portable-builder.d.ts +215 -0
  200. package/dist/portable-builder.d.ts.map +1 -0
  201. package/dist/portable-builder.js +27 -0
  202. package/dist/portable-builder.js.map +1 -0
  203. package/dist/portable-entry.d.ts +16 -0
  204. package/dist/portable-entry.d.ts.map +1 -0
  205. package/dist/portable-entry.js +14 -0
  206. package/dist/portable-entry.js.map +1 -0
  207. package/dist/position-reference-build.d.ts +29 -0
  208. package/dist/position-reference-build.d.ts.map +1 -0
  209. package/dist/position-reference-build.js +115 -0
  210. package/dist/position-reference-build.js.map +1 -0
  211. package/dist/position-reference.d.ts +34 -0
  212. package/dist/position-reference.d.ts.map +1 -0
  213. package/dist/position-reference.js +19 -0
  214. package/dist/position-reference.js.map +1 -0
  215. package/dist/runtime.d.ts +139 -0
  216. package/dist/runtime.d.ts.map +1 -0
  217. package/dist/runtime.js +2 -0
  218. package/dist/runtime.js.map +1 -0
  219. package/dist/scale-color-helpers.d.ts +121 -0
  220. package/dist/scale-color-helpers.d.ts.map +1 -0
  221. package/dist/scale-color-helpers.js +188 -0
  222. package/dist/scale-color-helpers.js.map +1 -0
  223. package/dist/scale-color-hue-grey.d.ts +52 -0
  224. package/dist/scale-color-hue-grey.d.ts.map +1 -0
  225. package/dist/scale-color-hue-grey.js +60 -0
  226. package/dist/scale-color-hue-grey.js.map +1 -0
  227. package/dist/scale-color-stops.d.ts +85 -0
  228. package/dist/scale-color-stops.d.ts.map +1 -0
  229. package/dist/scale-color-stops.js +87 -0
  230. package/dist/scale-color-stops.js.map +1 -0
  231. package/dist/scale-color-viridis.d.ts +52 -0
  232. package/dist/scale-color-viridis.d.ts.map +1 -0
  233. package/dist/scale-color-viridis.js +68 -0
  234. package/dist/scale-color-viridis.js.map +1 -0
  235. package/dist/scale-helpers.d.ts +20 -0
  236. package/dist/scale-helpers.d.ts.map +1 -0
  237. package/dist/scale-helpers.js +20 -0
  238. package/dist/scale-helpers.js.map +1 -0
  239. package/dist/scale-multi-helpers.d.ts +61 -0
  240. package/dist/scale-multi-helpers.d.ts.map +1 -0
  241. package/dist/scale-multi-helpers.js +147 -0
  242. package/dist/scale-multi-helpers.js.map +1 -0
  243. package/dist/scale-position-helpers.d.ts +81 -0
  244. package/dist/scale-position-helpers.d.ts.map +1 -0
  245. package/dist/scale-position-helpers.js +133 -0
  246. package/dist/scale-position-helpers.js.map +1 -0
  247. package/dist/scale-reference-build.d.ts +50 -0
  248. package/dist/scale-reference-build.d.ts.map +1 -0
  249. package/dist/scale-reference-build.js +147 -0
  250. package/dist/scale-reference-build.js.map +1 -0
  251. package/dist/scale-reference-classify-color.d.ts +11 -0
  252. package/dist/scale-reference-classify-color.d.ts.map +1 -0
  253. package/dist/scale-reference-classify-color.js +292 -0
  254. package/dist/scale-reference-classify-color.js.map +1 -0
  255. package/dist/scale-reference-classify-position.d.ts +10 -0
  256. package/dist/scale-reference-classify-position.d.ts.map +1 -0
  257. package/dist/scale-reference-classify-position.js +137 -0
  258. package/dist/scale-reference-classify-position.js.map +1 -0
  259. package/dist/scale-reference-classify-style.d.ts +10 -0
  260. package/dist/scale-reference-classify-style.d.ts.map +1 -0
  261. package/dist/scale-reference-classify-style.js +194 -0
  262. package/dist/scale-reference-classify-style.js.map +1 -0
  263. package/dist/scale-reference-classify-support.d.ts +37 -0
  264. package/dist/scale-reference-classify-support.d.ts.map +1 -0
  265. package/dist/scale-reference-classify-support.js +206 -0
  266. package/dist/scale-reference-classify-support.js.map +1 -0
  267. package/dist/scale-reference.d.ts +80 -0
  268. package/dist/scale-reference.d.ts.map +1 -0
  269. package/dist/scale-reference.js +85 -0
  270. package/dist/scale-reference.js.map +1 -0
  271. package/dist/scale-style-helpers.d.ts +158 -0
  272. package/dist/scale-style-helpers.d.ts.map +1 -0
  273. package/dist/scale-style-helpers.js +197 -0
  274. package/dist/scale-style-helpers.js.map +1 -0
  275. package/dist/schema-catalog.d.ts +62 -0
  276. package/dist/schema-catalog.d.ts.map +1 -0
  277. package/dist/schema-catalog.js +208 -0
  278. package/dist/schema-catalog.js.map +1 -0
  279. package/dist/schema-declarations.d.ts +1585 -0
  280. package/dist/schema-declarations.d.ts.map +1 -0
  281. package/dist/schema-declarations.js +51 -0
  282. package/dist/schema-declarations.js.map +1 -0
  283. package/dist/schema-decls-data.d.ts +58 -0
  284. package/dist/schema-decls-data.d.ts.map +1 -0
  285. package/dist/schema-decls-data.js +151 -0
  286. package/dist/schema-decls-data.js.map +1 -0
  287. package/dist/schema-decls-guides-theme.d.ts +166 -0
  288. package/dist/schema-decls-guides-theme.d.ts.map +1 -0
  289. package/dist/schema-decls-guides-theme.js +251 -0
  290. package/dist/schema-decls-guides-theme.js.map +1 -0
  291. package/dist/schema-decls-layers-col-boxplot.d.ts +118 -0
  292. package/dist/schema-decls-layers-col-boxplot.d.ts.map +1 -0
  293. package/dist/schema-decls-layers-col-boxplot.js +239 -0
  294. package/dist/schema-decls-layers-col-boxplot.js.map +1 -0
  295. package/dist/schema-decls-layers-count-pointrange.d.ts +89 -0
  296. package/dist/schema-decls-layers-count-pointrange.d.ts.map +1 -0
  297. package/dist/schema-decls-layers-count-pointrange.js +190 -0
  298. package/dist/schema-decls-layers-count-pointrange.js.map +1 -0
  299. package/dist/schema-decls-layers-crossbar-jitter.d.ts +129 -0
  300. package/dist/schema-decls-layers-crossbar-jitter.d.ts.map +1 -0
  301. package/dist/schema-decls-layers-crossbar-jitter.js +255 -0
  302. package/dist/schema-decls-layers-crossbar-jitter.js.map +1 -0
  303. package/dist/schema-decls-layers-point-path.d.ts +49 -0
  304. package/dist/schema-decls-layers-point-path.d.ts.map +1 -0
  305. package/dist/schema-decls-layers-point-path.js +156 -0
  306. package/dist/schema-decls-layers-point-path.js.map +1 -0
  307. package/dist/schema-decls-layers-sf-blank.d.ts +89 -0
  308. package/dist/schema-decls-layers-sf-blank.d.ts.map +1 -0
  309. package/dist/schema-decls-layers-sf-blank.js +254 -0
  310. package/dist/schema-decls-layers-sf-blank.js.map +1 -0
  311. package/dist/schema-decls-layers-text-map.d.ts +80 -0
  312. package/dist/schema-decls-layers-text-map.d.ts.map +1 -0
  313. package/dist/schema-decls-layers-text-map.js +151 -0
  314. package/dist/schema-decls-layers-text-map.js.map +1 -0
  315. package/dist/schema-decls-paint.d.ts +39 -0
  316. package/dist/schema-decls-paint.d.ts.map +1 -0
  317. package/dist/schema-decls-paint.js +95 -0
  318. package/dist/schema-decls-paint.js.map +1 -0
  319. package/dist/schema-decls-params-area-abline.d.ts +85 -0
  320. package/dist/schema-decls-params-area-abline.d.ts.map +1 -0
  321. package/dist/schema-decls-params-area-abline.js +259 -0
  322. package/dist/schema-decls-params-area-abline.js.map +1 -0
  323. package/dist/schema-decls-params-col-contour.d.ts +61 -0
  324. package/dist/schema-decls-params-col-contour.d.ts.map +1 -0
  325. package/dist/schema-decls-params-col-contour.js +202 -0
  326. package/dist/schema-decls-params-col-contour.js.map +1 -0
  327. package/dist/schema-decls-params-curve-label.d.ts +64 -0
  328. package/dist/schema-decls-params-curve-label.d.ts.map +1 -0
  329. package/dist/schema-decls-params-curve-label.js +204 -0
  330. package/dist/schema-decls-params-curve-label.js.map +1 -0
  331. package/dist/schema-decls-params-errorbar-position.d.ts +83 -0
  332. package/dist/schema-decls-params-errorbar-position.d.ts.map +1 -0
  333. package/dist/schema-decls-params-errorbar-position.js +264 -0
  334. package/dist/schema-decls-params-errorbar-position.js.map +1 -0
  335. package/dist/schema-decls-params-point-path.d.ts +61 -0
  336. package/dist/schema-decls-params-point-path.d.ts.map +1 -0
  337. package/dist/schema-decls-params-point-path.js +240 -0
  338. package/dist/schema-decls-params-point-path.js.map +1 -0
  339. package/dist/schema-decls-params-violin-summary.d.ts +78 -0
  340. package/dist/schema-decls-params-violin-summary.d.ts.map +1 -0
  341. package/dist/schema-decls-params-violin-summary.js +272 -0
  342. package/dist/schema-decls-params-violin-summary.js.map +1 -0
  343. package/dist/schema-decls-plot.d.ts +80 -0
  344. package/dist/schema-decls-plot.d.ts.map +1 -0
  345. package/dist/schema-decls-plot.js +222 -0
  346. package/dist/schema-decls-plot.js.map +1 -0
  347. package/dist/schema-decls-scales-guides.d.ts +291 -0
  348. package/dist/schema-decls-scales-guides.d.ts.map +1 -0
  349. package/dist/schema-decls-scales-guides.js +189 -0
  350. package/dist/schema-decls-scales-guides.js.map +1 -0
  351. package/dist/schema-decls-scales.d.ts +124 -0
  352. package/dist/schema-decls-scales.d.ts.map +1 -0
  353. package/dist/schema-decls-scales.js +279 -0
  354. package/dist/schema-decls-scales.js.map +1 -0
  355. package/dist/schema-imports.d.ts +1679 -0
  356. package/dist/schema-imports.d.ts.map +1 -0
  357. package/dist/schema-imports.js +104 -0
  358. package/dist/schema-imports.js.map +1 -0
  359. package/dist/schema-name-schemas.d.ts +18 -0
  360. package/dist/schema-name-schemas.d.ts.map +1 -0
  361. package/dist/schema-name-schemas.js +13 -0
  362. package/dist/schema-name-schemas.js.map +1 -0
  363. package/dist/schema-names.d.ts +53 -0
  364. package/dist/schema-names.d.ts.map +1 -0
  365. package/dist/schema-names.js +229 -0
  366. package/dist/schema-names.js.map +1 -0
  367. package/dist/schema-types.d.ts +336 -0
  368. package/dist/schema-types.d.ts.map +1 -0
  369. package/dist/schema-types.js +10 -0
  370. package/dist/schema-types.js.map +1 -0
  371. package/dist/schema.d.ts +38 -0
  372. package/dist/schema.d.ts.map +1 -0
  373. package/dist/schema.js +34 -0
  374. package/dist/schema.js.map +1 -0
  375. package/dist/stat-reference-build.d.ts +24 -0
  376. package/dist/stat-reference-build.d.ts.map +1 -0
  377. package/dist/stat-reference-build.js +86 -0
  378. package/dist/stat-reference-build.js.map +1 -0
  379. package/dist/stat-reference.d.ts +33 -0
  380. package/dist/stat-reference.d.ts.map +1 -0
  381. package/dist/stat-reference.js +19 -0
  382. package/dist/stat-reference.js.map +1 -0
  383. package/dist/structural-gate.d.ts +15 -0
  384. package/dist/structural-gate.d.ts.map +1 -0
  385. package/dist/structural-gate.js +34 -0
  386. package/dist/structural-gate.js.map +1 -0
  387. package/dist/temporal-column.d.ts +33 -0
  388. package/dist/temporal-column.d.ts.map +1 -0
  389. package/dist/temporal-column.js +247 -0
  390. package/dist/temporal-column.js.map +1 -0
  391. package/dist/temporal-guides.d.ts +11 -0
  392. package/dist/temporal-guides.d.ts.map +1 -0
  393. package/dist/temporal-guides.js +11 -0
  394. package/dist/temporal-guides.js.map +1 -0
  395. package/dist/temporal-interval-schema.d.ts +9 -0
  396. package/dist/temporal-interval-schema.d.ts.map +1 -0
  397. package/dist/temporal-interval-schema.js +25 -0
  398. package/dist/temporal-interval-schema.js.map +1 -0
  399. package/dist/temporal-interval.d.ts +29 -0
  400. package/dist/temporal-interval.d.ts.map +1 -0
  401. package/dist/temporal-interval.js +122 -0
  402. package/dist/temporal-interval.js.map +1 -0
  403. package/dist/temporal-parse-core.d.ts +96 -0
  404. package/dist/temporal-parse-core.d.ts.map +1 -0
  405. package/dist/temporal-parse-core.js +235 -0
  406. package/dist/temporal-parse-core.js.map +1 -0
  407. package/dist/temporal-parse-format.d.ts +13 -0
  408. package/dist/temporal-parse-format.d.ts.map +1 -0
  409. package/dist/temporal-parse-format.js +180 -0
  410. package/dist/temporal-parse-format.js.map +1 -0
  411. package/dist/temporal-parse-schema.d.ts +11 -0
  412. package/dist/temporal-parse-schema.d.ts.map +1 -0
  413. package/dist/temporal-parse-schema.js +23 -0
  414. package/dist/temporal-parse-schema.js.map +1 -0
  415. package/dist/temporal-parse.d.ts +18 -0
  416. package/dist/temporal-parse.d.ts.map +1 -0
  417. package/dist/temporal-parse.js +183 -0
  418. package/dist/temporal-parse.js.map +1 -0
  419. package/dist/temporal-polyfill.d.ts +3 -0
  420. package/dist/temporal-polyfill.d.ts.map +1 -0
  421. package/dist/temporal-polyfill.js +25 -0
  422. package/dist/temporal-polyfill.js.map +1 -0
  423. package/dist/temporal-ticks.d.ts +20 -0
  424. package/dist/temporal-ticks.d.ts.map +1 -0
  425. package/dist/temporal-ticks.js +246 -0
  426. package/dist/temporal-ticks.js.map +1 -0
  427. package/dist/temporal.d.ts +109 -0
  428. package/dist/temporal.d.ts.map +1 -0
  429. package/dist/temporal.js +73 -0
  430. package/dist/temporal.js.map +1 -0
  431. package/dist/validate-data-checks-color-temporal.d.ts +58 -0
  432. package/dist/validate-data-checks-color-temporal.d.ts.map +1 -0
  433. package/dist/validate-data-checks-color-temporal.js +168 -0
  434. package/dist/validate-data-checks-color-temporal.js.map +1 -0
  435. package/dist/validate-data-checks-color.d.ts +28 -0
  436. package/dist/validate-data-checks-color.d.ts.map +1 -0
  437. package/dist/validate-data-checks-color.js +296 -0
  438. package/dist/validate-data-checks-color.js.map +1 -0
  439. package/dist/validate-data-checks-layer.d.ts +37 -0
  440. package/dist/validate-data-checks-layer.d.ts.map +1 -0
  441. package/dist/validate-data-checks-layer.js +343 -0
  442. package/dist/validate-data-checks-layer.js.map +1 -0
  443. package/dist/validate-data-checks-position.d.ts +45 -0
  444. package/dist/validate-data-checks-position.d.ts.map +1 -0
  445. package/dist/validate-data-checks-position.js +204 -0
  446. package/dist/validate-data-checks-position.js.map +1 -0
  447. package/dist/validate-data-checks-style-finite.d.ts +24 -0
  448. package/dist/validate-data-checks-style-finite.d.ts.map +1 -0
  449. package/dist/validate-data-checks-style-finite.js +40 -0
  450. package/dist/validate-data-checks-style-finite.js.map +1 -0
  451. package/dist/validate-data-checks-style-numeric.d.ts +26 -0
  452. package/dist/validate-data-checks-style-numeric.d.ts.map +1 -0
  453. package/dist/validate-data-checks-style-numeric.js +327 -0
  454. package/dist/validate-data-checks-style-numeric.js.map +1 -0
  455. package/dist/validate-data-checks-style.d.ts +14 -0
  456. package/dist/validate-data-checks-style.d.ts.map +1 -0
  457. package/dist/validate-data-checks-style.js +14 -0
  458. package/dist/validate-data-checks-style.js.map +1 -0
  459. package/dist/validate-data-checks-temporal.d.ts +57 -0
  460. package/dist/validate-data-checks-temporal.d.ts.map +1 -0
  461. package/dist/validate-data-checks-temporal.js +83 -0
  462. package/dist/validate-data-checks-temporal.js.map +1 -0
  463. package/dist/validate-data-checks.d.ts +31 -0
  464. package/dist/validate-data-checks.d.ts.map +1 -0
  465. package/dist/validate-data-checks.js +110 -0
  466. package/dist/validate-data-checks.js.map +1 -0
  467. package/dist/validate-data-evidence.d.ts +69 -0
  468. package/dist/validate-data-evidence.d.ts.map +1 -0
  469. package/dist/validate-data-evidence.js +329 -0
  470. package/dist/validate-data-evidence.js.map +1 -0
  471. package/dist/validate-data.d.ts +73 -0
  472. package/dist/validate-data.d.ts.map +1 -0
  473. package/dist/validate-data.js +30 -0
  474. package/dist/validate-data.js.map +1 -0
  475. package/dist/validate-map-errors.d.ts +32 -0
  476. package/dist/validate-map-errors.d.ts.map +1 -0
  477. package/dist/validate-map-errors.js +76 -0
  478. package/dist/validate-map-errors.js.map +1 -0
  479. package/dist/validate-map-forms.d.ts +43 -0
  480. package/dist/validate-map-forms.d.ts.map +1 -0
  481. package/dist/validate-map-forms.js +125 -0
  482. package/dist/validate-map-forms.js.map +1 -0
  483. package/dist/validate-map-path-keywords.d.ts +11 -0
  484. package/dist/validate-map-path-keywords.d.ts.map +1 -0
  485. package/dist/validate-map-path-keywords.js +95 -0
  486. package/dist/validate-map-path-keywords.js.map +1 -0
  487. package/dist/validate-map-path-unions.d.ts +27 -0
  488. package/dist/validate-map-path-unions.d.ts.map +1 -0
  489. package/dist/validate-map-path-unions.js +200 -0
  490. package/dist/validate-map-path-unions.js.map +1 -0
  491. package/dist/validate-schema-shape.d.ts +69 -0
  492. package/dist/validate-schema-shape.d.ts.map +1 -0
  493. package/dist/validate-schema-shape.js +156 -0
  494. package/dist/validate-schema-shape.js.map +1 -0
  495. package/dist/validate-schema-walk.d.ts +34 -0
  496. package/dist/validate-schema-walk.d.ts.map +1 -0
  497. package/dist/validate-schema-walk.js +216 -0
  498. package/dist/validate-schema-walk.js.map +1 -0
  499. package/dist/validate-structure-facet.d.ts +8 -0
  500. package/dist/validate-structure-facet.d.ts.map +1 -0
  501. package/dist/validate-structure-facet.js +67 -0
  502. package/dist/validate-structure-facet.js.map +1 -0
  503. package/dist/validate-structure-layer-computed-y.d.ts +14 -0
  504. package/dist/validate-structure-layer-computed-y.d.ts.map +1 -0
  505. package/dist/validate-structure-layer-computed-y.js +70 -0
  506. package/dist/validate-structure-layer-computed-y.js.map +1 -0
  507. package/dist/validate-structure-layer-ribbon.d.ts +8 -0
  508. package/dist/validate-structure-layer-ribbon.d.ts.map +1 -0
  509. package/dist/validate-structure-layer-ribbon.js +36 -0
  510. package/dist/validate-structure-layer-ribbon.js.map +1 -0
  511. package/dist/validate-structure-layer-rule.d.ts +14 -0
  512. package/dist/validate-structure-layer-rule.d.ts.map +1 -0
  513. package/dist/validate-structure-layer-rule.js +90 -0
  514. package/dist/validate-structure-layer-rule.js.map +1 -0
  515. package/dist/validate-structure-layer-shared.d.ts +12 -0
  516. package/dist/validate-structure-layer-shared.d.ts.map +1 -0
  517. package/dist/validate-structure-layer-shared.js +17 -0
  518. package/dist/validate-structure-layer-shared.js.map +1 -0
  519. package/dist/validate-structure-layers.d.ts +12 -0
  520. package/dist/validate-structure-layers.d.ts.map +1 -0
  521. package/dist/validate-structure-layers.js +292 -0
  522. package/dist/validate-structure-layers.js.map +1 -0
  523. package/dist/validate-structure-paint.d.ts +12 -0
  524. package/dist/validate-structure-paint.d.ts.map +1 -0
  525. package/dist/validate-structure-paint.js +87 -0
  526. package/dist/validate-structure-paint.js.map +1 -0
  527. package/dist/validate-structure-scales.d.ts +10 -0
  528. package/dist/validate-structure-scales.d.ts.map +1 -0
  529. package/dist/validate-structure-scales.js +242 -0
  530. package/dist/validate-structure-scales.js.map +1 -0
  531. package/dist/validate-structure-style-bins.d.ts +17 -0
  532. package/dist/validate-structure-style-bins.d.ts.map +1 -0
  533. package/dist/validate-structure-style-bins.js +150 -0
  534. package/dist/validate-structure-style-bins.js.map +1 -0
  535. package/dist/validate-structure.d.ts +16 -0
  536. package/dist/validate-structure.d.ts.map +1 -0
  537. package/dist/validate-structure.js +16 -0
  538. package/dist/validate-structure.js.map +1 -0
  539. package/dist/validate.d.ts +24 -0
  540. package/dist/validate.d.ts.map +1 -0
  541. package/dist/validate.js +178 -0
  542. package/dist/validate.js.map +1 -0
  543. package/package.json +59 -0
  544. package/schema/v0.json +9618 -0
  545. package/src/artifact.ts +81 -0
  546. package/src/builder-core.ts +276 -0
  547. package/src/builder-data.ts +156 -0
  548. package/src/builder-geoms.ts +290 -0
  549. package/src/builder-options.ts +428 -0
  550. package/src/builder-scales.ts +443 -0
  551. package/src/builder.ts +125 -0
  552. package/src/capabilities-data.ts +336 -0
  553. package/src/capabilities-helpers.ts +54 -0
  554. package/src/capabilities.ts +159 -0
  555. package/src/coord-helpers.ts +177 -0
  556. package/src/coord-reference-build.ts +283 -0
  557. package/src/coord-reference.ts +75 -0
  558. package/src/error-catalog.ts +253 -0
  559. package/src/error-prose-shared.ts +106 -0
  560. package/src/errors.ts +87 -0
  561. package/src/generated/coord-reference-data.ts +235 -0
  562. package/src/generated/geom-param-keys.ts +222 -0
  563. package/src/generated/geom-reference-data.ts +3024 -0
  564. package/src/generated/guide-reference-data.ts +284 -0
  565. package/src/generated/plot-spec-validator.ts +7335 -0
  566. package/src/generated/position-reference-data.ts +191 -0
  567. package/src/generated/scale-reference-data.ts +10665 -0
  568. package/src/generated/stat-reference-data.ts +339 -0
  569. package/src/geom-params-build.ts +92 -0
  570. package/src/geom-params.ts +14 -0
  571. package/src/geom-reference-build.ts +292 -0
  572. package/src/geom-reference.ts +127 -0
  573. package/src/guide-helpers.ts +44 -0
  574. package/src/guide-reference-build.ts +249 -0
  575. package/src/guide-reference.ts +76 -0
  576. package/src/hue-grey-palettes.ts +82 -0
  577. package/src/index.ts +400 -0
  578. package/src/lint-catalog.ts +57 -0
  579. package/src/lint-layer-rules.ts +175 -0
  580. package/src/lint-scale-rules.ts +285 -0
  581. package/src/lint.ts +126 -0
  582. package/src/normalize-coord.ts +126 -0
  583. package/src/normalize-input-layers-marks.ts +276 -0
  584. package/src/normalize-input-layers-special.ts +252 -0
  585. package/src/normalize-input.ts +154 -0
  586. package/src/normalize-paint.ts +98 -0
  587. package/src/normalize-scales.ts +108 -0
  588. package/src/normalize.ts +403 -0
  589. package/src/paint-helpers.ts +98 -0
  590. package/src/pipeline-error-catalog.ts +278 -0
  591. package/src/portability-check.ts +155 -0
  592. package/src/portability-lossy.ts +81 -0
  593. package/src/portability.ts +31 -0
  594. package/src/portable-builder.ts +35 -0
  595. package/src/portable-entry.ts +37 -0
  596. package/src/position-reference-build.ts +164 -0
  597. package/src/position-reference.ts +41 -0
  598. package/src/runtime.ts +198 -0
  599. package/src/scale-color-helpers.ts +263 -0
  600. package/src/scale-color-hue-grey.ts +95 -0
  601. package/src/scale-color-stops.ts +177 -0
  602. package/src/scale-color-viridis.ts +99 -0
  603. package/src/scale-helpers.ts +264 -0
  604. package/src/scale-multi-helpers.ts +220 -0
  605. package/src/scale-position-helpers.ts +231 -0
  606. package/src/scale-reference-build.ts +222 -0
  607. package/src/scale-reference-classify-color.ts +334 -0
  608. package/src/scale-reference-classify-position.ts +164 -0
  609. package/src/scale-reference-classify-style.ts +229 -0
  610. package/src/scale-reference-classify-support.ts +298 -0
  611. package/src/scale-reference.ts +165 -0
  612. package/src/scale-style-helpers.ts +316 -0
  613. package/src/schema-catalog.ts +222 -0
  614. package/src/schema-declarations.ts +51 -0
  615. package/src/schema-decls-data.ts +272 -0
  616. package/src/schema-decls-guides-theme.ts +395 -0
  617. package/src/schema-decls-layers-col-boxplot.ts +410 -0
  618. package/src/schema-decls-layers-count-pointrange.ts +321 -0
  619. package/src/schema-decls-layers-crossbar-jitter.ts +443 -0
  620. package/src/schema-decls-layers-point-path.ts +246 -0
  621. package/src/schema-decls-layers-sf-blank.ts +408 -0
  622. package/src/schema-decls-layers-text-map.ts +259 -0
  623. package/src/schema-decls-paint.ts +124 -0
  624. package/src/schema-decls-params-area-abline.ts +440 -0
  625. package/src/schema-decls-params-col-contour.ts +333 -0
  626. package/src/schema-decls-params-curve-label.ts +343 -0
  627. package/src/schema-decls-params-errorbar-position.ts +446 -0
  628. package/src/schema-decls-params-point-path.ts +394 -0
  629. package/src/schema-decls-params-violin-summary.ts +447 -0
  630. package/src/schema-decls-plot.ts +385 -0
  631. package/src/schema-decls-scales-guides.ts +233 -0
  632. package/src/schema-decls-scales.ts +432 -0
  633. package/src/schema-imports.ts +116 -0
  634. package/src/schema-name-schemas.ts +37 -0
  635. package/src/schema-names.ts +243 -0
  636. package/src/schema-types.ts +400 -0
  637. package/src/schema.ts +287 -0
  638. package/src/stat-reference-build.ts +145 -0
  639. package/src/stat-reference.ts +38 -0
  640. package/src/structural-gate.ts +42 -0
  641. package/src/temporal-column.ts +323 -0
  642. package/src/temporal-guides.ts +32 -0
  643. package/src/temporal-interval-schema.ts +40 -0
  644. package/src/temporal-interval.ts +151 -0
  645. package/src/temporal-parse-core.ts +331 -0
  646. package/src/temporal-parse-format.ts +222 -0
  647. package/src/temporal-parse-schema.ts +38 -0
  648. package/src/temporal-parse.ts +259 -0
  649. package/src/temporal-polyfill.ts +27 -0
  650. package/src/temporal-ticks.ts +312 -0
  651. package/src/temporal.ts +112 -0
  652. package/src/validate-data-checks-color-temporal.ts +261 -0
  653. package/src/validate-data-checks-color.ts +395 -0
  654. package/src/validate-data-checks-layer.ts +492 -0
  655. package/src/validate-data-checks-position.ts +275 -0
  656. package/src/validate-data-checks-style-finite.ts +55 -0
  657. package/src/validate-data-checks-style-numeric.ts +455 -0
  658. package/src/validate-data-checks-style.ts +13 -0
  659. package/src/validate-data-checks-temporal.ts +129 -0
  660. package/src/validate-data-checks.ts +157 -0
  661. package/src/validate-data-evidence.ts +419 -0
  662. package/src/validate-data.ts +114 -0
  663. package/src/validate-map-errors.ts +126 -0
  664. package/src/validate-map-forms.ts +148 -0
  665. package/src/validate-map-path-keywords.ts +129 -0
  666. package/src/validate-map-path-unions.ts +281 -0
  667. package/src/validate-schema-shape.ts +232 -0
  668. package/src/validate-schema-walk.ts +219 -0
  669. package/src/validate-structure-facet.ts +76 -0
  670. package/src/validate-structure-layer-computed-y.ts +94 -0
  671. package/src/validate-structure-layer-ribbon.ts +61 -0
  672. package/src/validate-structure-layer-rule.ts +98 -0
  673. package/src/validate-structure-layer-shared.ts +29 -0
  674. package/src/validate-structure-layers.ts +395 -0
  675. package/src/validate-structure-paint.ts +101 -0
  676. package/src/validate-structure-scales.ts +278 -0
  677. package/src/validate-structure-style-bins.ts +167 -0
  678. package/src/validate-structure.ts +16 -0
  679. package/src/validate.ts +212 -0
@@ -0,0 +1,455 @@
1
+ /**
2
+ * Size/linewidth/alpha sequential/binned data-aware scale checks (incl. temporal).
3
+ * Barrel: validate-data-checks-style.ts. Orchestrator: validate-data-checks.ts.
4
+ */
5
+ import type { SpecError } from "./errors.js";
6
+ import { parseTemporalColumn, type TemporalDecision } from "./temporal-column.js";
7
+ import { parseTemporal } from "./temporal-parse.js";
8
+ import type { FieldEvidenceEntry, FieldEvidenceMap } from "./validate-data-evidence.js";
9
+ import {
10
+ temporalDecisionForField,
11
+ temporalParserUsable,
12
+ type ChannelFieldUse,
13
+ type TemporalDecisionCache,
14
+ } from "./validate-data-checks-temporal.js";
15
+
16
+ type NumericStyleConfig = {
17
+ type?: string;
18
+ temporalKind?: unknown;
19
+ parse?: unknown;
20
+ timezone?: unknown;
21
+ disambiguation?: unknown;
22
+ domain?: unknown;
23
+ parseFailure?: unknown;
24
+ breaks?: unknown;
25
+ };
26
+
27
+ type NumericStyleFacts = {
28
+ requestsTemporal: boolean;
29
+ temporalInputsUsable: boolean;
30
+ parser: Parameters<typeof parseTemporalColumn>[1];
31
+ temporalOptions: Parameters<typeof parseTemporalColumn>[2];
32
+ hasEpochParser: boolean;
33
+ hasExplicitDomain: boolean;
34
+ hasBinnedBreaks: boolean;
35
+ };
36
+
37
+ /** True when a scaled constant is what the core `cellToNumber()` coerces to a
38
+ * finite number, mirroring the non-temporal numeric-style path
39
+ * (scale-style-values.ts). Booleans, numeric strings and ISO date strings all
40
+ * train and render at runtime, so validation must accept them too. Core's
41
+ * cellToNumber cannot be imported here (core depends on spec, not vice versa),
42
+ * so the predicate is replicated. */
43
+ function scaledConstantCoercesToFinite(value: unknown): boolean {
44
+ if (typeof value === "number") return Number.isFinite(value);
45
+ if (value instanceof Date) return Number.isFinite(value.getTime());
46
+ if (typeof value === "boolean") return true;
47
+ if (typeof value === "string") {
48
+ if (parseTemporal(value, "iso").ok) return true;
49
+ return value.trim() !== "" && Number.isFinite(Number(value));
50
+ }
51
+ return false;
52
+ }
53
+
54
+ /** Format an arbitrary value for a diagnostic message without ever throwing.
55
+ * Tier-2 runs after schema errors, so a schema-invalid JS constant (BigInt,
56
+ * Symbol, circular object) can reach a message; JSON.stringify throws on BigInt
57
+ * and String() throws on Symbol, so fall back through both to the type name. */
58
+ function safeFormatConstant(value: unknown): string {
59
+ try {
60
+ const json = JSON.stringify(value);
61
+ if (json !== undefined) return json;
62
+ } catch {
63
+ /* BigInt / circular — fall through */
64
+ }
65
+ try {
66
+ return String(value);
67
+ } catch {
68
+ return typeof value;
69
+ }
70
+ }
71
+
72
+ /** A quantitative field carrying temporal options resolves at runtime only when a
73
+ * working parser (or censor recovery) yields temporal values. Returns a mismatch
74
+ * error or null. Extracted to keep the field loop within the max-depth limit. */
75
+ function quantitativeTemporalFieldError(input: {
76
+ decision: TemporalDecision | null | undefined;
77
+ aesthetic: "size" | "linewidth" | "alpha";
78
+ field: string;
79
+ temporalKind: unknown;
80
+ parse: unknown;
81
+ parseFailure: unknown;
82
+ hasEpochParser: boolean;
83
+ hasExplicitDomain: boolean;
84
+ hasBinnedBreaks: boolean;
85
+ /** Channel-wide training (sibling fields / scaled constants) for parseFailure: "censor". */
86
+ channelTrains: boolean;
87
+ }): SpecError | null {
88
+ const {
89
+ decision,
90
+ aesthetic,
91
+ field,
92
+ temporalKind,
93
+ parse,
94
+ parseFailure,
95
+ hasEpochParser,
96
+ hasExplicitDomain,
97
+ hasBinnedBreaks,
98
+ channelTrains,
99
+ } = input;
100
+ const mismatch: SpecError = {
101
+ code: "scale-type-mismatch",
102
+ path: `/scales/${aesthetic}`,
103
+ message: `scales.${aesthetic} requests temporal values but field "${field}" is quantitative (numbers are not treated as temporal without a successful epoch parse).`,
104
+ fix: {
105
+ description: `Map a temporal field, use a working parse: { epoch: "ms" | "s" }, or remove temporal ${aesthetic} options.`,
106
+ },
107
+ };
108
+ const censorRecovers =
109
+ parseFailure === "censor" && (hasExplicitDomain || hasBinnedBreaks || channelTrains);
110
+ if (decision === null || decision === undefined) {
111
+ return profileQuantitativeTemporalError({
112
+ aesthetic,
113
+ temporalKind,
114
+ hasEpochParser,
115
+ censorRecovers,
116
+ mismatch,
117
+ });
118
+ }
119
+ const censoredInvalid =
120
+ parse !== undefined &&
121
+ parseFailure === "censor" &&
122
+ decision.status === "invalid" &&
123
+ ((decision.validatedCount ?? 0) > 0 || hasExplicitDomain || hasBinnedBreaks || channelTrains);
124
+ if (decision.status !== "temporal" && !censoredInvalid) return mismatch;
125
+ // temporalKind may be a schema-invalid non-string (e.g. a Symbol) reaching tier-2;
126
+ // only compare/stringify when it is a valid string, else defer to the schema diagnostic.
127
+ if (
128
+ typeof temporalKind === "string" &&
129
+ decision.kind !== null &&
130
+ decision.kind !== undefined &&
131
+ decision.kind !== temporalKind
132
+ ) {
133
+ return {
134
+ code: "scale-type-mismatch",
135
+ path: `/scales/${aesthetic}`,
136
+ message: `scales.${aesthetic} requests temporal kind "${temporalKind}" but field "${field}" parses as "${decision.kind}".`,
137
+ fix: {
138
+ description: `Use the ${decision.kind ?? "matching"} ${aesthetic} helper or correct the source precision.`,
139
+ },
140
+ };
141
+ }
142
+ return null;
143
+ }
144
+
145
+ function profileQuantitativeTemporalError(input: {
146
+ aesthetic: "size" | "linewidth" | "alpha";
147
+ temporalKind: unknown;
148
+ hasEpochParser: boolean;
149
+ censorRecovers: boolean;
150
+ mismatch: SpecError;
151
+ }): SpecError | null {
152
+ const { aesthetic, temporalKind, hasEpochParser, censorRecovers, mismatch } = input;
153
+ if (hasEpochParser && typeof temporalKind === "string" && temporalKind !== "datetime") {
154
+ return {
155
+ code: "scale-type-mismatch",
156
+ path: `/scales/${aesthetic}`,
157
+ message: `scales.${aesthetic} requests temporal kind "${temporalKind}" but an epoch parser yields "datetime".`,
158
+ fix: {
159
+ description: `Set scales.${aesthetic}.temporalKind to "datetime", or use a parser that yields ${temporalKind} values.`,
160
+ },
161
+ };
162
+ }
163
+ return hasEpochParser || censorRecovers ? null : mismatch;
164
+ }
165
+
166
+ /** A scaled numeric-style constant is checked against the same resolution path the
167
+ * runtime uses (resolveNumericStyleValueView). Returns a mismatch error, or null when
168
+ * the constant resolves. Extracted so the per-constant branching does not nest under
169
+ * the aesthetic/constant loops (max-depth). */
170
+ function numericStyleConstantError(input: {
171
+ value: unknown;
172
+ aesthetic: "size" | "linewidth" | "alpha";
173
+ configType: string;
174
+ requestsTemporal: boolean;
175
+ temporalKind: unknown;
176
+ parseUsable: boolean;
177
+ parser: Parameters<typeof parseTemporalColumn>[1];
178
+ options: Parameters<typeof parseTemporalColumn>[2];
179
+ censorRecovers: boolean;
180
+ }): SpecError | null {
181
+ const {
182
+ value,
183
+ aesthetic,
184
+ configType,
185
+ requestsTemporal,
186
+ temporalKind,
187
+ parseUsable,
188
+ parser,
189
+ options,
190
+ censorRecovers,
191
+ } = input;
192
+ if (!requestsTemporal) {
193
+ // Non-temporal: accept exactly what cellToNumber() coerces to a finite number
194
+ // (numbers, Dates, booleans, numeric strings, ISO strings); reject "large", "", null.
195
+ if (scaledConstantCoercesToFinite(value)) return null;
196
+ return {
197
+ code: "scale-type-mismatch",
198
+ path: `/scales/${aesthetic}`,
199
+ message: `scales.${aesthetic}.type is "${configType}" but the scaled constant ${safeFormatConstant(value)} is not numeric; ${configType} ${aesthetic} scales need quantitative or temporal values.`,
200
+ fix: {
201
+ description: `Use a numeric scaled constant, or set scales.${aesthetic}.type to "ordinal".`,
202
+ example: { type: "ordinal" },
203
+ },
204
+ };
205
+ }
206
+ // Temporal: a schema-invalid parser defers to the schema error; otherwise the constant
207
+ // must resolve temporal (a Date is datetime), or be covered by censor recovery.
208
+ if (!parseUsable) return null;
209
+ let constantKind: string | null | undefined;
210
+ if (value instanceof Date) {
211
+ constantKind = "datetime";
212
+ } else if (typeof value === "string" || typeof value === "number") {
213
+ const decision = parseTemporalColumn(
214
+ [value] as Parameters<typeof parseTemporalColumn>[0],
215
+ parser,
216
+ options,
217
+ ).decision;
218
+ constantKind = decision.status === "temporal" ? (decision.kind ?? null) : undefined;
219
+ } else {
220
+ // boolean, bigint, symbol, object, null: not a temporal constant, and must not be
221
+ // handed to parseTemporalColumn — its evidence formatting (JSON.stringify) throws on
222
+ // BigInt / unserializable objects. safeFormatConstant handles the message safely.
223
+ constantKind = undefined;
224
+ }
225
+ if (constantKind === undefined) {
226
+ if (censorRecovers) return null;
227
+ return {
228
+ code: "scale-type-mismatch",
229
+ path: `/scales/${aesthetic}`,
230
+ message: `scales.${aesthetic} requests temporal values but the scaled constant ${safeFormatConstant(value)} is not temporal; use a temporal constant or a working parse.`,
231
+ fix: {
232
+ description: `Use a temporal scaled constant, add a working parse: { epoch: "ms" | "s" }, or remove temporal ${aesthetic} options.`,
233
+ },
234
+ };
235
+ }
236
+ // The constant parses temporal; enforce the requested kind — the runtime throws
237
+ // style-temporal-kind when a datetime constant is fed to a `date` scale (or vice versa).
238
+ if (typeof temporalKind === "string" && constantKind !== null && constantKind !== temporalKind) {
239
+ return {
240
+ code: "scale-type-mismatch",
241
+ path: `/scales/${aesthetic}`,
242
+ message: `scales.${aesthetic} requests temporal kind "${temporalKind}" but the scaled constant ${safeFormatConstant(value)} parses as "${constantKind}".`,
243
+ fix: {
244
+ description: `Use a ${temporalKind} constant, or set scales.${aesthetic}.temporalKind to "${constantKind}".`,
245
+ },
246
+ };
247
+ }
248
+ return null;
249
+ }
250
+
251
+ /**
252
+ * Size/linewidth/alpha sequential/binned scale vs field/constant types (incl. temporal).
253
+ * Prefers per-use evidenceForUse over the last-wins union so multi-table same-name
254
+ * fields keep independent types (#609 / #844).
255
+ */
256
+ export function checkNumericStyleScaleDataCompatibility(input: {
257
+ scales: Record<string, unknown> | undefined;
258
+ fields: FieldEvidenceMap;
259
+ /**
260
+ * Optional per-use evidence lookup. When provided, prefer it over the
261
+ * last-wins `fields` union so multi-table layers with the same field name
262
+ * keep their own type evidence (#609 / #844).
263
+ */
264
+ evidenceForUse?: (use: ChannelFieldUse) => FieldEvidenceEntry | undefined;
265
+ numericStyleFields: Record<"size" | "linewidth" | "alpha", ChannelFieldUse[]>;
266
+ numericStyleScaledConstants: Record<"size" | "linewidth" | "alpha", unknown[]>;
267
+ temporalDecisionCache: TemporalDecisionCache;
268
+ }): SpecError[] {
269
+ const { scales, fields, numericStyleFields, numericStyleScaledConstants, temporalDecisionCache } =
270
+ input;
271
+ const errors: SpecError[] = [];
272
+ const evidenceOf = (use: ChannelFieldUse) => input.evidenceForUse?.(use) ?? fields.get(use.field);
273
+ const typeOf = (use: ChannelFieldUse) => evidenceOf(use)?.type ?? null;
274
+ // color check: a continuous ramp needs quantitative or temporal values, so a
275
+ // nominal/ordinal field trains no finite domain and the runtime throws
276
+ // `style-domain-empty` (scale-style.ts). Reject it at validation time with the
277
+ // same "use ordinal" guidance color scales give. Fields without an explicit
278
+ // sequential/binned type default to an ordinal numeric style and are fine.
279
+ for (const aesthetic of ["size", "linewidth", "alpha"] as const) {
280
+ const config = scales?.[aesthetic] as NumericStyleConfig | undefined;
281
+ if (config?.type !== "sequential" && config?.type !== "binned") continue;
282
+ const facts = numericStyleFacts(config);
283
+ // Pass 1: channel-wide training sources (sibling fields + scaled constants).
284
+ // Runtime trains sequential/binned style scales from the full channel value
285
+ // list, so an all-invalid field/constant is censored when any sibling trains.
286
+ const channelTrains = numericStyleChannelTrains({
287
+ uses: numericStyleFields[aesthetic],
288
+ constants: numericStyleScaledConstants[aesthetic],
289
+ evidenceOf,
290
+ typeOf,
291
+ cache: temporalDecisionCache,
292
+ facts,
293
+ });
294
+
295
+ // Pass 2: field diagnostics (use channel-wide censor recovery).
296
+ for (const use of numericStyleFields[aesthetic]) {
297
+ const type = typeOf(use);
298
+ // A quantitative field carrying temporal options fails at resolve time
299
+ // unless a working parser (or censor recovery) yields temporal values —
300
+ // mirror the color checker rather than deferring unconditionally.
301
+ if (type === "quantitative" && facts.requestsTemporal) {
302
+ // Defer to the schema diagnostic when the parser/options are schema-invalid.
303
+ if (!facts.temporalInputsUsable) continue;
304
+ const decision = temporalDecisionForField(
305
+ temporalDecisionCache,
306
+ use.field,
307
+ evidenceOf(use),
308
+ facts.parser as Parameters<typeof temporalDecisionForField>[3],
309
+ facts.temporalOptions as Parameters<typeof temporalDecisionForField>[4],
310
+ );
311
+ const error = quantitativeTemporalFieldError({
312
+ decision,
313
+ aesthetic,
314
+ field: use.field,
315
+ temporalKind: config.temporalKind,
316
+ parse: config.parse,
317
+ parseFailure: config.parseFailure,
318
+ hasEpochParser: facts.hasEpochParser,
319
+ hasExplicitDomain: facts.hasExplicitDomain,
320
+ hasBinnedBreaks: facts.hasBinnedBreaks,
321
+ channelTrains,
322
+ });
323
+ if (error !== null) errors.push(error);
324
+ }
325
+ // A nominal/ordinal field trains no finite domain and the runtime throws
326
+ // `style-domain-empty`; reject it with the same "use ordinal" guidance color
327
+ // scales give. A nominal field carrying temporal options may still resolve
328
+ // to temporal at runtime, so defer (mirror the color checker).
329
+ if (type !== "nominal" && type !== "ordinal") continue;
330
+ if (facts.requestsTemporal) continue;
331
+ errors.push({
332
+ code: "scale-type-mismatch",
333
+ path: `/scales/${aesthetic}`,
334
+ message: `scales.${aesthetic}.type is "${config.type}" but field "${use.field}" is ${type}; ${config.type} ${aesthetic} scales need quantitative or temporal values.`,
335
+ fix: {
336
+ description: `Set scales.${aesthetic}.type to "ordinal", or map a quantitative field.`,
337
+ example: { type: "ordinal" },
338
+ },
339
+ });
340
+ }
341
+ // Scaled constants train the same numeric scale, so a constant the scale can't
342
+ // resolve throws at runtime (style-domain-empty / style-temporal-parse). Reject
343
+ // it here too, mirroring the field checks above for both resolution paths.
344
+ const censorRecovers =
345
+ config.parseFailure === "censor" &&
346
+ (facts.hasExplicitDomain || facts.hasBinnedBreaks || channelTrains);
347
+ for (const value of numericStyleScaledConstants[aesthetic]) {
348
+ const error = numericStyleConstantError({
349
+ value,
350
+ aesthetic,
351
+ configType: config.type,
352
+ requestsTemporal: facts.requestsTemporal,
353
+ temporalKind: config.temporalKind,
354
+ parseUsable: facts.temporalInputsUsable,
355
+ parser: facts.parser,
356
+ options: facts.temporalOptions,
357
+ censorRecovers,
358
+ });
359
+ if (error !== null) errors.push(error);
360
+ }
361
+ }
362
+ return errors;
363
+ }
364
+
365
+ function numericStyleFacts(config: NumericStyleConfig): NumericStyleFacts {
366
+ const requestsTemporal = [
367
+ config.temporalKind,
368
+ config.parse,
369
+ config.timezone,
370
+ config.disambiguation,
371
+ ].some((value) => value !== undefined);
372
+ const temporalInputsUsable =
373
+ temporalParserUsable(config.parse) &&
374
+ (config.timezone === undefined || typeof config.timezone === "string") &&
375
+ (config.disambiguation === undefined || typeof config.disambiguation === "string");
376
+ const parser = (config.parse ?? "auto") as Parameters<typeof parseTemporalColumn>[1];
377
+ const temporalOptions = {
378
+ ...(config.timezone !== undefined && { timezone: config.timezone }),
379
+ ...(config.disambiguation !== undefined && { disambiguation: config.disambiguation }),
380
+ } as Parameters<typeof parseTemporalColumn>[2];
381
+ const parseableBound = (value: unknown): boolean =>
382
+ temporalInputsUsable &&
383
+ config.parse !== undefined &&
384
+ parseTemporal(value, config.parse as Parameters<typeof parseTemporal>[1], temporalOptions).ok;
385
+ const domainValues = Array.isArray(config.domain) ? config.domain.filter(nonNull) : [];
386
+ const binnedBreaks =
387
+ config.type === "binned" && Array.isArray(config.breaks) ? config.breaks.filter(nonNull) : [];
388
+ return {
389
+ requestsTemporal,
390
+ temporalInputsUsable,
391
+ parser,
392
+ temporalOptions,
393
+ hasEpochParser:
394
+ typeof config.parse === "object" && config.parse !== null && "epoch" in config.parse,
395
+ hasExplicitDomain:
396
+ domainValues.length === 2 && domainValues.every((value) => parseableBound(value)),
397
+ hasBinnedBreaks:
398
+ binnedBreaks.length >= 2 && binnedBreaks.every((value) => parseableBound(value)),
399
+ };
400
+ }
401
+
402
+ function nonNull(value: unknown): boolean {
403
+ return value !== null;
404
+ }
405
+
406
+ function numericStyleChannelTrains(input: {
407
+ uses: ChannelFieldUse[];
408
+ constants: unknown[];
409
+ evidenceOf: (use: ChannelFieldUse) => FieldEvidenceEntry | undefined;
410
+ typeOf: (use: ChannelFieldUse) => FieldEvidenceEntry["type"] | null;
411
+ cache: TemporalDecisionCache;
412
+ facts: NumericStyleFacts;
413
+ }): boolean {
414
+ const { uses, constants, evidenceOf, typeOf, cache, facts } = input;
415
+ if (uses.some((use) => fieldTrainsNumericStyle(use, evidenceOf, typeOf, cache, facts)))
416
+ return true;
417
+ if (!facts.requestsTemporal || !facts.temporalInputsUsable) return false;
418
+ return constants.some((value) => constantTrainsNumericStyle(value, facts));
419
+ }
420
+
421
+ function fieldTrainsNumericStyle(
422
+ use: ChannelFieldUse,
423
+ evidenceOf: (use: ChannelFieldUse) => FieldEvidenceEntry | undefined,
424
+ typeOf: (use: ChannelFieldUse) => FieldEvidenceEntry["type"] | null,
425
+ cache: TemporalDecisionCache,
426
+ facts: NumericStyleFacts,
427
+ ): boolean {
428
+ const type = typeOf(use);
429
+ if (type === "temporal") return true;
430
+ if (type !== "quantitative" || !facts.requestsTemporal || !facts.temporalInputsUsable)
431
+ return false;
432
+ const decision = temporalDecisionForField(
433
+ cache,
434
+ use.field,
435
+ evidenceOf(use),
436
+ facts.parser as Parameters<typeof temporalDecisionForField>[3],
437
+ facts.temporalOptions as Parameters<typeof temporalDecisionForField>[4],
438
+ );
439
+ return (
440
+ decision !== null &&
441
+ decision !== undefined &&
442
+ (decision.status === "temporal" || (decision.validatedCount ?? 0) > 0)
443
+ );
444
+ }
445
+
446
+ function constantTrainsNumericStyle(value: unknown, facts: NumericStyleFacts): boolean {
447
+ if (value instanceof Date) return true;
448
+ if (typeof value !== "string" && typeof value !== "number") return false;
449
+ const decision = parseTemporalColumn(
450
+ [value] as Parameters<typeof parseTemporalColumn>[0],
451
+ facts.parser,
452
+ facts.temporalOptions,
453
+ ).decision;
454
+ return decision.status === "temporal" || (decision.validatedCount ?? 0) > 0;
455
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Style aesthetic data-aware scale checks (shape/linetype finite symbols;
3
+ * size/linewidth/alpha sequential/binned + temporal).
4
+ *
5
+ * - validate-data-checks-style-finite.ts — shape / linetype
6
+ * - validate-data-checks-style-numeric.ts — size / linewidth / alpha
7
+ *
8
+ * Shared temporal memoization: validate-data-checks-temporal.ts.
9
+ * Position: validate-data-checks-position.ts. Color: validate-data-checks-color.ts.
10
+ * Orchestrator: validate-data-checks.ts.
11
+ */
12
+ export { checkFiniteStyleScaleDataCompatibility } from "./validate-data-checks-style-finite.js";
13
+ export { checkNumericStyleScaleDataCompatibility } from "./validate-data-checks-style-numeric.js";
@@ -0,0 +1,129 @@
1
+ /**
2
+ * Shared temporal decision memoization for data-aware scale checks.
3
+ * Used by position (x/y), color/fill, and numeric style scale compatibility.
4
+ * Orchestrator: validate-data-checks.ts.
5
+ */
6
+ import type { SpecError } from "./errors.js";
7
+ import { parseTemporalColumn, type TemporalDecision } from "./temporal-column.js";
8
+ import {
9
+ canonicalTemporalParserKey,
10
+ type TemporalParseOptions,
11
+ type TemporalParserSpec,
12
+ type TemporalScaleKind,
13
+ } from "./temporal-parse.js";
14
+ import type { FieldEvidenceEntry } from "./validate-data-evidence.js";
15
+
16
+ /** Channel field use collected during the layer walk (position or color). */
17
+ export interface ChannelFieldUse {
18
+ field: string;
19
+ path: string;
20
+ }
21
+
22
+ /**
23
+ * True when a scale's `parse` value is safe to hand to temporalDecisionForField.
24
+ *
25
+ * A schema-invalid parser (e.g. `123`, `true`, `{}`, `[]`) is collected as a
26
+ * schema error, but tier-2 data checks still run, so a malformed value can reach
27
+ * this helper's `canonicalTemporalParserKey` — which does `"epoch" in parser`
28
+ * (throws on a non-object) and reads `parser.format` (throws inside fnv1a on an
29
+ * empty object). Only `undefined`, a string, or a well-formed `{ epoch }` /
30
+ * `{ format }` object is usable; anything else must defer to the schema
31
+ * diagnostic instead of crashing validation.
32
+ */
33
+ export function temporalParserUsable(parse: unknown): boolean {
34
+ if (parse === undefined || typeof parse === "string") return true;
35
+ if (typeof parse !== "object" || parse === null || Array.isArray(parse)) return false;
36
+ return (
37
+ typeof (parse as { epoch?: unknown }).epoch === "string" ||
38
+ typeof (parse as { format?: unknown }).format === "string"
39
+ );
40
+ }
41
+
42
+ /**
43
+ * One cache per dataChecks() call — shared by position, color, and style checkers.
44
+ *
45
+ * Outer key: field + parser + timezone + disambiguation.
46
+ * Inner key: the FieldEvidenceEntry object (null when info is missing). Layers
47
+ * that share a named dataset reuse the same entry object, so multi-consumer
48
+ * memoization still hits. Layers with different datasets get different entries
49
+ * and must not share a decision under the same field name (#1339).
50
+ */
51
+ export type TemporalDecisionCache = Map<
52
+ string,
53
+ Map<FieldEvidenceEntry | null, TemporalDecision | null | undefined>
54
+ >;
55
+
56
+ /**
57
+ * Resolve one field's temporal decision for scale compatibility checks.
58
+ *
59
+ * Memoized per dataChecks() call so multi-layer / multi-channel consumers of
60
+ * the same field evidence under the same parser+options pay O(n) once, not O(U·n).
61
+ * When parser is auto and options match the evidence pass (no timezone /
62
+ * disambiguation), reuse FieldEvidenceEntry.temporal instead of re-scanning.
63
+ *
64
+ * Cache key omits parseFailure and temporalKind — those only affect how the
65
+ * decision is interpreted, not the decision itself. Dataset identity is the
66
+ * FieldEvidenceEntry object identity (inner map key).
67
+ */
68
+ export function temporalDecisionForField(
69
+ cache: TemporalDecisionCache,
70
+ field: string,
71
+ info: FieldEvidenceEntry | undefined,
72
+ parser: TemporalParserSpec | "auto",
73
+ options: TemporalParseOptions,
74
+ ): TemporalDecision | null | undefined {
75
+ const parserKey = parser === "auto" ? "auto" : canonicalTemporalParserKey(parser);
76
+ const key = `${field}\0${parserKey}\0${options.timezone ?? ""}\0${options.disambiguation ?? ""}`;
77
+ let byInfo = cache.get(key);
78
+ if (byInfo === undefined) {
79
+ byInfo = new Map();
80
+ cache.set(key, byInfo);
81
+ }
82
+ const infoKey = info ?? null;
83
+ if (byInfo.has(infoKey)) return byInfo.get(infoKey);
84
+
85
+ let decision: TemporalDecision | null | undefined;
86
+ if (info?.values === null || info?.values === undefined) {
87
+ // Profile-backed fields: no inline values. temporal is always null today.
88
+ decision = info?.temporal ?? null;
89
+ } else if (
90
+ parser === "auto" &&
91
+ options.timezone === undefined &&
92
+ options.disambiguation === undefined &&
93
+ info.temporal !== null
94
+ ) {
95
+ // Evidence was built with inferTemporalColumn(column) — same auto defaults.
96
+ decision = info.temporal;
97
+ } else {
98
+ decision = parseTemporalColumn(info.values, parser, options).decision;
99
+ }
100
+ byInfo.set(infoKey, decision);
101
+ return decision;
102
+ }
103
+
104
+ export function appendTemporalKindMismatch(
105
+ errors: SpecError[],
106
+ input: {
107
+ axis: "x" | "y";
108
+ path: string;
109
+ field: string;
110
+ expected: TemporalScaleKind | undefined;
111
+ actual: "date" | "datetime" | "time" | null;
112
+ },
113
+ ): void {
114
+ const { axis, path, field, expected, actual } = input;
115
+ if (expected === undefined || actual === null || actual === expected) return;
116
+ // scale_*_time reduces date/datetime to UTC clock portion (#831); not a mismatch.
117
+ if (expected === "time" && (actual === "date" || actual === "datetime")) return;
118
+ // monthDay takes the month-day off a full date and drops the rest, so a field
119
+ // parsing as date or datetime is exactly what it expects to be given.
120
+ if (expected === "monthDay" && (actual === "date" || actual === "datetime")) return;
121
+ errors.push({
122
+ code: "scale-type-mismatch",
123
+ path,
124
+ message: `scales.${axis}.temporalKind is "${expected}" but field "${field}" parses as ${actual}.`,
125
+ fix: {
126
+ description: `Use temporalKind "${actual}" or choose a parser that produces ${expected} values.`,
127
+ },
128
+ });
129
+ }