@platforma-sdk/model 1.63.1 → 1.64.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 (399) hide show
  1. package/dist/_virtual/_rolldown/runtime.cjs +12 -22
  2. package/dist/_virtual/_rolldown/runtime.js +6 -11
  3. package/dist/annotations/converter.cjs +4 -5
  4. package/dist/annotations/converter.cjs.map +1 -1
  5. package/dist/annotations/converter.d.ts.map +1 -0
  6. package/dist/annotations/converter.js +1 -2
  7. package/dist/annotations/converter.js.map +1 -1
  8. package/dist/annotations/index.cjs +1 -1
  9. package/dist/annotations/index.js +1 -1
  10. package/dist/annotations/types.d.ts +0 -1
  11. package/dist/annotations/types.d.ts.map +1 -0
  12. package/dist/bconfig/index.cjs +2 -2
  13. package/dist/bconfig/index.js +2 -2
  14. package/dist/bconfig/lambdas.d.ts +0 -1
  15. package/dist/bconfig/lambdas.d.ts.map +1 -0
  16. package/dist/bconfig/normalization.cjs +4 -5
  17. package/dist/bconfig/normalization.cjs.map +1 -1
  18. package/dist/bconfig/normalization.d.ts.map +1 -0
  19. package/dist/bconfig/normalization.js +1 -2
  20. package/dist/bconfig/normalization.js.map +1 -1
  21. package/dist/bconfig/types.cjs +1 -2
  22. package/dist/bconfig/types.cjs.map +1 -1
  23. package/dist/bconfig/types.d.ts +0 -1
  24. package/dist/bconfig/types.d.ts.map +1 -0
  25. package/dist/bconfig/types.js +1 -1
  26. package/dist/bconfig/util.d.ts.map +1 -0
  27. package/dist/bconfig/v3.d.ts.map +1 -0
  28. package/dist/block_api_v1.d.ts.map +1 -0
  29. package/dist/block_api_v2.d.ts.map +1 -0
  30. package/dist/block_api_v3.d.ts.map +1 -0
  31. package/dist/block_migrations.cjs +2 -3
  32. package/dist/block_migrations.cjs.map +1 -1
  33. package/dist/block_migrations.d.ts.map +1 -0
  34. package/dist/block_migrations.js +1 -2
  35. package/dist/block_migrations.js.map +1 -1
  36. package/dist/block_model.cjs +16 -17
  37. package/dist/block_model.cjs.map +1 -1
  38. package/dist/block_model.d.ts +0 -2
  39. package/dist/block_model.d.ts.map +1 -0
  40. package/dist/block_model.js +4 -5
  41. package/dist/block_model.js.map +1 -1
  42. package/dist/block_model_legacy.cjs +10 -11
  43. package/dist/block_model_legacy.cjs.map +1 -1
  44. package/dist/block_model_legacy.d.ts +0 -3
  45. package/dist/block_model_legacy.d.ts.map +1 -0
  46. package/dist/block_model_legacy.js +1 -2
  47. package/dist/block_model_legacy.js.map +1 -1
  48. package/dist/block_state_patch.d.ts.map +1 -0
  49. package/dist/block_state_util.cjs +1 -2
  50. package/dist/block_state_util.cjs.map +1 -1
  51. package/dist/block_state_util.d.ts.map +1 -0
  52. package/dist/block_state_util.js +1 -1
  53. package/dist/block_state_util.js.map +1 -1
  54. package/dist/block_storage.cjs +5 -12
  55. package/dist/block_storage.cjs.map +1 -1
  56. package/dist/block_storage.d.ts.map +1 -0
  57. package/dist/block_storage.js +5 -11
  58. package/dist/block_storage.js.map +1 -1
  59. package/dist/block_storage_callbacks.cjs +4 -5
  60. package/dist/block_storage_callbacks.cjs.map +1 -1
  61. package/dist/block_storage_callbacks.js +3 -4
  62. package/dist/block_storage_callbacks.js.map +1 -1
  63. package/dist/block_storage_facade.cjs +2 -3
  64. package/dist/block_storage_facade.cjs.map +1 -1
  65. package/dist/block_storage_facade.d.ts +0 -1
  66. package/dist/block_storage_facade.d.ts.map +1 -0
  67. package/dist/block_storage_facade.js +1 -2
  68. package/dist/block_storage_facade.js.map +1 -1
  69. package/dist/columns/column_collection_builder.cjs +111 -99
  70. package/dist/columns/column_collection_builder.cjs.map +1 -1
  71. package/dist/columns/column_collection_builder.d.ts +13 -12
  72. package/dist/columns/column_collection_builder.d.ts.map +1 -0
  73. package/dist/columns/column_collection_builder.js +108 -96
  74. package/dist/columns/column_collection_builder.js.map +1 -1
  75. package/dist/columns/column_selector.cjs +9 -82
  76. package/dist/columns/column_selector.cjs.map +1 -1
  77. package/dist/columns/column_selector.d.ts +6 -14
  78. package/dist/columns/column_selector.d.ts.map +1 -0
  79. package/dist/columns/column_selector.js +7 -78
  80. package/dist/columns/column_selector.js.map +1 -1
  81. package/dist/columns/column_snapshot.cjs +4 -5
  82. package/dist/columns/column_snapshot.cjs.map +1 -1
  83. package/dist/columns/column_snapshot.d.ts +3 -3
  84. package/dist/columns/column_snapshot.d.ts.map +1 -0
  85. package/dist/columns/column_snapshot.js +4 -4
  86. package/dist/columns/column_snapshot.js.map +1 -1
  87. package/dist/columns/column_snapshot_provider.cjs +2 -3
  88. package/dist/columns/column_snapshot_provider.cjs.map +1 -1
  89. package/dist/columns/column_snapshot_provider.d.ts +8 -8
  90. package/dist/columns/column_snapshot_provider.d.ts.map +1 -0
  91. package/dist/columns/column_snapshot_provider.js +2 -2
  92. package/dist/columns/column_snapshot_provider.js.map +1 -1
  93. package/dist/columns/ctx_column_sources.cjs +3 -4
  94. package/dist/columns/ctx_column_sources.cjs.map +1 -1
  95. package/dist/columns/ctx_column_sources.d.ts +2 -2
  96. package/dist/columns/ctx_column_sources.d.ts.map +1 -0
  97. package/dist/columns/ctx_column_sources.js +1 -2
  98. package/dist/columns/ctx_column_sources.js.map +1 -1
  99. package/dist/columns/expand_by_partition.cjs +106 -0
  100. package/dist/columns/expand_by_partition.cjs.map +1 -0
  101. package/dist/columns/expand_by_partition.d.ts +33 -0
  102. package/dist/columns/expand_by_partition.d.ts.map +1 -0
  103. package/dist/columns/expand_by_partition.js +105 -0
  104. package/dist/columns/expand_by_partition.js.map +1 -0
  105. package/dist/columns/index.cjs +6 -5
  106. package/dist/columns/index.d.ts +4 -3
  107. package/dist/columns/index.js +6 -5
  108. package/dist/components/PFrameForGraphs.cjs +4 -5
  109. package/dist/components/PFrameForGraphs.cjs.map +1 -1
  110. package/dist/components/PFrameForGraphs.d.ts +0 -1
  111. package/dist/components/PFrameForGraphs.d.ts.map +1 -0
  112. package/dist/components/PFrameForGraphs.js +2 -3
  113. package/dist/components/PFrameForGraphs.js.map +1 -1
  114. package/dist/components/PlAnnotations/filter.d.ts.map +1 -0
  115. package/dist/components/PlAnnotations/filters_ui.cjs +1 -2
  116. package/dist/components/PlAnnotations/filters_ui.cjs.map +1 -1
  117. package/dist/components/PlAnnotations/filters_ui.d.ts +0 -2
  118. package/dist/components/PlAnnotations/filters_ui.d.ts.map +1 -0
  119. package/dist/components/PlAnnotations/filters_ui.js +1 -1
  120. package/dist/components/PlAnnotations/filters_ui.js.map +1 -1
  121. package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.cjs +26 -0
  122. package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.cjs.map +1 -0
  123. package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.js +25 -0
  124. package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.js.map +1 -0
  125. package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.cjs +68 -0
  126. package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.cjs.map +1 -0
  127. package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.js +67 -0
  128. package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.js.map +1 -0
  129. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.cjs +28 -18
  130. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.cjs.map +1 -1
  131. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.d.ts +4 -1
  132. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.d.ts.map +1 -0
  133. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.js +22 -12
  134. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.js.map +1 -1
  135. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.cjs +262 -181
  136. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.cjs.map +1 -1
  137. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.d.ts +37 -23
  138. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.d.ts.map +1 -0
  139. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js +261 -177
  140. package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js.map +1 -1
  141. package/dist/components/PlDataTable/createPlDataTable/discoverColumns.cjs +64 -0
  142. package/dist/components/PlDataTable/createPlDataTable/discoverColumns.cjs.map +1 -0
  143. package/dist/components/PlDataTable/createPlDataTable/discoverColumns.d.ts +17 -0
  144. package/dist/components/PlDataTable/createPlDataTable/discoverColumns.d.ts.map +1 -0
  145. package/dist/components/PlDataTable/createPlDataTable/discoverColumns.js +63 -0
  146. package/dist/components/PlDataTable/createPlDataTable/discoverColumns.js.map +1 -0
  147. package/dist/components/PlDataTable/createPlDataTable/index.cjs +4 -4
  148. package/dist/components/PlDataTable/createPlDataTable/index.cjs.map +1 -1
  149. package/dist/components/PlDataTable/createPlDataTable/index.d.ts +2 -2
  150. package/dist/components/PlDataTable/createPlDataTable/index.d.ts.map +1 -0
  151. package/dist/components/PlDataTable/createPlDataTable/index.js +3 -3
  152. package/dist/components/PlDataTable/createPlDataTable/index.js.map +1 -1
  153. package/dist/components/PlDataTable/createPlDataTable/utils.cjs +109 -0
  154. package/dist/components/PlDataTable/createPlDataTable/utils.cjs.map +1 -0
  155. package/dist/components/PlDataTable/createPlDataTable/utils.d.ts +19 -0
  156. package/dist/components/PlDataTable/createPlDataTable/utils.d.ts.map +1 -0
  157. package/dist/components/PlDataTable/createPlDataTable/utils.js +102 -0
  158. package/dist/components/PlDataTable/createPlDataTable/utils.js.map +1 -0
  159. package/dist/components/PlDataTable/createPlDataTableSheet.cjs +1 -2
  160. package/dist/components/PlDataTable/createPlDataTableSheet.cjs.map +1 -1
  161. package/dist/components/PlDataTable/createPlDataTableSheet.d.ts +0 -1
  162. package/dist/components/PlDataTable/createPlDataTableSheet.d.ts.map +1 -0
  163. package/dist/components/PlDataTable/createPlDataTableSheet.js +1 -1
  164. package/dist/components/PlDataTable/index.cjs +7 -5
  165. package/dist/components/PlDataTable/index.d.ts +4 -2
  166. package/dist/components/PlDataTable/index.js +7 -5
  167. package/dist/components/PlDataTable/labels.cjs +27 -14
  168. package/dist/components/PlDataTable/labels.cjs.map +1 -1
  169. package/dist/components/PlDataTable/labels.js +26 -13
  170. package/dist/components/PlDataTable/labels.js.map +1 -1
  171. package/dist/components/PlDataTable/state-migration.cjs +8 -6
  172. package/dist/components/PlDataTable/state-migration.cjs.map +1 -1
  173. package/dist/components/PlDataTable/state-migration.d.ts.map +1 -0
  174. package/dist/components/PlDataTable/state-migration.js +5 -3
  175. package/dist/components/PlDataTable/state-migration.js.map +1 -1
  176. package/dist/components/PlDataTable/typesV4.d.ts.map +1 -0
  177. package/dist/components/PlDataTable/typesV5.d.ts +5 -5
  178. package/dist/components/PlDataTable/typesV5.d.ts.map +1 -0
  179. package/dist/components/PlMultiSequenceAlignment.cjs +2 -3
  180. package/dist/components/PlMultiSequenceAlignment.cjs.map +1 -1
  181. package/dist/components/PlMultiSequenceAlignment.d.ts.map +1 -0
  182. package/dist/components/PlMultiSequenceAlignment.js +1 -2
  183. package/dist/components/PlMultiSequenceAlignment.js.map +1 -1
  184. package/dist/components/PlSelectionModel.cjs +1 -2
  185. package/dist/components/PlSelectionModel.cjs.map +1 -1
  186. package/dist/components/PlSelectionModel.d.ts.map +1 -0
  187. package/dist/components/PlSelectionModel.js +1 -1
  188. package/dist/components/index.cjs +13 -11
  189. package/dist/components/index.d.ts +3 -3
  190. package/dist/components/index.js +12 -10
  191. package/dist/config/actions.cjs +1 -2
  192. package/dist/config/actions.cjs.map +1 -1
  193. package/dist/config/actions.d.ts.map +1 -0
  194. package/dist/config/actions.js +1 -1
  195. package/dist/config/actions_kinds.d.ts.map +1 -0
  196. package/dist/config/index.cjs +1 -1
  197. package/dist/config/index.js +1 -1
  198. package/dist/config/model.d.ts.map +1 -0
  199. package/dist/config/model_meta.d.ts.map +1 -0
  200. package/dist/config/type_engine.d.ts.map +1 -0
  201. package/dist/config/type_util.d.ts.map +1 -0
  202. package/dist/env_value.cjs +1 -2
  203. package/dist/env_value.cjs.map +1 -1
  204. package/dist/env_value.d.ts.map +1 -0
  205. package/dist/env_value.js +1 -1
  206. package/dist/env_value.js.map +1 -1
  207. package/dist/filters/converters/filterToQuery.cjs +3 -4
  208. package/dist/filters/converters/filterToQuery.cjs.map +1 -1
  209. package/dist/filters/converters/filterToQuery.d.ts.map +1 -0
  210. package/dist/filters/converters/filterToQuery.js +1 -2
  211. package/dist/filters/converters/filterToQuery.js.map +1 -1
  212. package/dist/filters/converters/filterUiToExpressionImpl.cjs +3 -4
  213. package/dist/filters/converters/filterUiToExpressionImpl.cjs.map +1 -1
  214. package/dist/filters/converters/filterUiToExpressionImpl.d.ts.map +1 -0
  215. package/dist/filters/converters/filterUiToExpressionImpl.js +1 -2
  216. package/dist/filters/converters/filterUiToExpressionImpl.js.map +1 -1
  217. package/dist/filters/converters/index.cjs +2 -2
  218. package/dist/filters/converters/index.js +2 -2
  219. package/dist/filters/distill.cjs +3 -4
  220. package/dist/filters/distill.cjs.map +1 -1
  221. package/dist/filters/distill.d.ts.map +1 -0
  222. package/dist/filters/distill.js +1 -2
  223. package/dist/filters/distill.js.map +1 -1
  224. package/dist/filters/index.cjs +4 -4
  225. package/dist/filters/index.d.ts +0 -1
  226. package/dist/filters/index.js +3 -3
  227. package/dist/filters/traverse.cjs +1 -2
  228. package/dist/filters/traverse.cjs.map +1 -1
  229. package/dist/filters/traverse.js +1 -1
  230. package/dist/filters/traverse.js.map +1 -1
  231. package/dist/filters/types.d.ts.map +1 -0
  232. package/dist/index.cjs +89 -83
  233. package/dist/index.d.ts +8 -15
  234. package/dist/index.js +8 -9
  235. package/dist/internal.cjs +1 -2
  236. package/dist/internal.cjs.map +1 -1
  237. package/dist/internal.js +1 -1
  238. package/dist/internal.js.map +1 -1
  239. package/dist/labels/derive_distinct_labels.cjs +41 -30
  240. package/dist/labels/derive_distinct_labels.cjs.map +1 -1
  241. package/dist/labels/derive_distinct_labels.d.ts +15 -15
  242. package/dist/labels/derive_distinct_labels.d.ts.map +1 -0
  243. package/dist/labels/derive_distinct_labels.js +40 -29
  244. package/dist/labels/derive_distinct_labels.js.map +1 -1
  245. package/dist/labels/index.cjs +1 -2
  246. package/dist/labels/index.d.ts +1 -2
  247. package/dist/labels/index.js +1 -2
  248. package/dist/package.cjs +7 -8
  249. package/dist/package.js +2 -2
  250. package/dist/pframe.cjs +2 -3
  251. package/dist/pframe.cjs.map +1 -1
  252. package/dist/pframe.d.ts.map +1 -0
  253. package/dist/pframe.js +1 -2
  254. package/dist/pframe.js.map +1 -1
  255. package/dist/pframe_utils/axes.cjs +2 -3
  256. package/dist/pframe_utils/axes.cjs.map +1 -1
  257. package/dist/pframe_utils/axes.d.ts +0 -1
  258. package/dist/pframe_utils/axes.d.ts.map +1 -0
  259. package/dist/pframe_utils/axes.js +1 -2
  260. package/dist/pframe_utils/axes.js.map +1 -1
  261. package/dist/pframe_utils/columns.cjs +5 -6
  262. package/dist/pframe_utils/columns.cjs.map +1 -1
  263. package/dist/pframe_utils/columns.d.ts +0 -1
  264. package/dist/pframe_utils/columns.d.ts.map +1 -0
  265. package/dist/pframe_utils/columns.js +1 -2
  266. package/dist/pframe_utils/columns.js.map +1 -1
  267. package/dist/pframe_utils/index.cjs +3 -4
  268. package/dist/pframe_utils/index.cjs.map +1 -1
  269. package/dist/pframe_utils/index.d.ts.map +1 -0
  270. package/dist/pframe_utils/index.js +2 -3
  271. package/dist/pframe_utils/index.js.map +1 -1
  272. package/dist/platforma.d.ts.map +1 -0
  273. package/dist/plugin_handle.cjs +1 -2
  274. package/dist/plugin_handle.cjs.map +1 -1
  275. package/dist/plugin_handle.d.ts.map +1 -0
  276. package/dist/plugin_handle.js +1 -1
  277. package/dist/plugin_model.cjs +3 -4
  278. package/dist/plugin_model.cjs.map +1 -1
  279. package/dist/plugin_model.d.ts +0 -1
  280. package/dist/plugin_model.d.ts.map +1 -0
  281. package/dist/plugin_model.js +1 -2
  282. package/dist/plugin_model.js.map +1 -1
  283. package/dist/raw_globals.cjs +3 -4
  284. package/dist/raw_globals.cjs.map +1 -1
  285. package/dist/raw_globals.d.ts.map +1 -0
  286. package/dist/raw_globals.js +1 -2
  287. package/dist/raw_globals.js.map +1 -1
  288. package/dist/ref_util.cjs +3 -4
  289. package/dist/ref_util.cjs.map +1 -1
  290. package/dist/ref_util.d.ts +0 -2
  291. package/dist/ref_util.d.ts.map +1 -0
  292. package/dist/ref_util.js +1 -2
  293. package/dist/ref_util.js.map +1 -1
  294. package/dist/render/accessor.cjs +4 -5
  295. package/dist/render/accessor.cjs.map +1 -1
  296. package/dist/render/accessor.d.ts.map +1 -0
  297. package/dist/render/accessor.js +1 -2
  298. package/dist/render/accessor.js.map +1 -1
  299. package/dist/render/api.cjs +20 -14
  300. package/dist/render/api.cjs.map +1 -1
  301. package/dist/render/api.d.ts +2 -3
  302. package/dist/render/api.d.ts.map +1 -0
  303. package/dist/render/api.js +11 -5
  304. package/dist/render/api.js.map +1 -1
  305. package/dist/render/future.cjs +2 -3
  306. package/dist/render/future.cjs.map +1 -1
  307. package/dist/render/future.d.ts.map +1 -0
  308. package/dist/render/future.js +1 -2
  309. package/dist/render/future.js.map +1 -1
  310. package/dist/render/index.cjs +8 -8
  311. package/dist/render/index.d.ts +1 -2
  312. package/dist/render/index.js +7 -7
  313. package/dist/render/internal.cjs +7 -9
  314. package/dist/render/internal.cjs.map +1 -1
  315. package/dist/render/internal.d.ts.map +1 -0
  316. package/dist/render/internal.js +1 -2
  317. package/dist/render/internal.js.map +1 -1
  318. package/dist/render/traversal_ops.d.ts.map +1 -0
  319. package/dist/render/util/axis_filtering.cjs +1 -2
  320. package/dist/render/util/axis_filtering.cjs.map +1 -1
  321. package/dist/render/util/axis_filtering.d.ts.map +1 -0
  322. package/dist/render/util/axis_filtering.js +1 -1
  323. package/dist/render/util/column_collection.cjs +8 -9
  324. package/dist/render/util/column_collection.cjs.map +1 -1
  325. package/dist/render/util/column_collection.d.ts +0 -1
  326. package/dist/render/util/column_collection.d.ts.map +1 -0
  327. package/dist/render/util/column_collection.js +4 -5
  328. package/dist/render/util/column_collection.js.map +1 -1
  329. package/dist/render/util/index.cjs +4 -4
  330. package/dist/render/util/index.js +4 -4
  331. package/dist/render/util/label.cjs +4 -5
  332. package/dist/render/util/label.cjs.map +1 -1
  333. package/dist/render/util/label.d.ts.map +1 -0
  334. package/dist/render/util/label.js +3 -4
  335. package/dist/render/util/label.js.map +1 -1
  336. package/dist/render/util/pcolumn_data.cjs +9 -10
  337. package/dist/render/util/pcolumn_data.cjs.map +1 -1
  338. package/dist/render/util/pcolumn_data.d.ts +2 -2
  339. package/dist/render/util/pcolumn_data.d.ts.map +1 -0
  340. package/dist/render/util/pcolumn_data.js +7 -8
  341. package/dist/render/util/pcolumn_data.js.map +1 -1
  342. package/dist/render/util/pframe_upgraders.cjs +1 -2
  343. package/dist/render/util/pframe_upgraders.cjs.map +1 -1
  344. package/dist/render/util/pframe_upgraders.js +1 -1
  345. package/dist/render/util/split_selectors.d.ts.map +1 -0
  346. package/dist/services/block_services.cjs +2 -3
  347. package/dist/services/block_services.cjs.map +1 -1
  348. package/dist/services/block_services.d.ts +2 -2
  349. package/dist/services/block_services.d.ts.map +1 -0
  350. package/dist/services/block_services.js +1 -2
  351. package/dist/services/block_services.js.map +1 -1
  352. package/dist/services/index.cjs +2 -2
  353. package/dist/services/index.js +2 -2
  354. package/dist/services/service_bridge.cjs +1 -2
  355. package/dist/services/service_bridge.cjs.map +1 -1
  356. package/dist/services/service_bridge.d.ts.map +1 -0
  357. package/dist/services/service_bridge.js +1 -1
  358. package/dist/services/service_resolve.d.ts.map +1 -0
  359. package/dist/version.cjs +2 -4
  360. package/dist/version.cjs.map +1 -1
  361. package/dist/version.d.ts.map +1 -0
  362. package/dist/version.js +1 -2
  363. package/dist/version.js.map +1 -1
  364. package/package.json +13 -13
  365. package/src/columns/column_collection_builder.test.ts +40 -27
  366. package/src/columns/column_collection_builder.ts +176 -131
  367. package/src/columns/column_selector.test.ts +17 -399
  368. package/src/columns/column_selector.ts +14 -127
  369. package/src/columns/column_snapshot.ts +5 -5
  370. package/src/columns/column_snapshot_provider.ts +11 -10
  371. package/src/columns/ctx_column_sources.ts +2 -2
  372. package/src/columns/expand_by_partition.test.ts +4 -4
  373. package/src/columns/expand_by_partition.ts +4 -3
  374. package/src/columns/index.ts +1 -0
  375. package/src/components/PlDataTable/createPlDataTable/createPTableDefV2.ts +42 -0
  376. package/src/components/PlDataTable/createPlDataTable/createPTableDefV3.ts +89 -0
  377. package/src/components/PlDataTable/createPlDataTable/createPlDataTableV2.ts +39 -11
  378. package/src/components/PlDataTable/createPlDataTable/createPlDataTableV3.ts +502 -313
  379. package/src/components/PlDataTable/createPlDataTable/discoverColumns.ts +122 -0
  380. package/src/components/PlDataTable/createPlDataTable/index.ts +4 -2
  381. package/src/components/PlDataTable/createPlDataTable/utils.test.ts +257 -0
  382. package/src/components/PlDataTable/createPlDataTable/utils.ts +160 -0
  383. package/src/components/PlDataTable/index.ts +13 -2
  384. package/src/components/PlDataTable/labels.ts +29 -18
  385. package/src/components/PlDataTable/state-migration.ts +3 -1
  386. package/src/components/PlDataTable/typesV5.ts +4 -4
  387. package/src/labels/derive_distinct_labels.test.ts +143 -45
  388. package/src/labels/derive_distinct_labels.ts +102 -49
  389. package/src/labels/index.ts +0 -1
  390. package/src/render/api.ts +15 -5
  391. package/src/render/util/column_collection.ts +4 -3
  392. package/src/render/util/label.ts +2 -2
  393. package/src/render/util/pcolumn_data.ts +5 -3
  394. package/dist/labels/write_labels_to_specs.cjs +0 -15
  395. package/dist/labels/write_labels_to_specs.cjs.map +0 -1
  396. package/dist/labels/write_labels_to_specs.d.ts +0 -9
  397. package/dist/labels/write_labels_to_specs.js +0 -14
  398. package/dist/labels/write_labels_to_specs.js.map +0 -1
  399. package/src/labels/write_labels_to_specs.ts +0 -12
@@ -1,47 +1,28 @@
1
- import type { MultiColumnSelector, PColumnSpec } from "@milaboratories/pl-model-common";
2
1
  import { describe, expect, test } from "vitest";
3
- import type { RelaxedColumnSelector } from "./column_selector";
4
- import {
5
- matchColumn,
6
- matchColumnSelectors,
7
- normalizeSelectors,
8
- columnSelectorsToPredicate,
9
- } from "./column_selector";
2
+ import { convertColumnSelectorToMultiColumnSelector } from "./column_selector";
10
3
  import type { RegExpString } from "@milaboratories/helpers";
11
4
 
12
- // --- Helpers ---
5
+ // --- convertColumnSelectorToMultiColumnSelector ---
13
6
 
14
- function spec(overrides: Partial<PColumnSpec> & { name: string }): PColumnSpec {
15
- return {
16
- kind: "PColumn",
17
- valueType: "Int",
18
- axesSpec: [],
19
- annotations: {},
20
- ...overrides,
21
- } as PColumnSpec;
22
- }
23
-
24
- // --- normalizeSelectors ---
25
-
26
- describe("normalizeSelectors", () => {
7
+ describe("convertColumnSelectorToMultiColumnSelector", () => {
27
8
  test("wraps single selector in array", () => {
28
- const result = normalizeSelectors({ name: "foo" });
9
+ const result = convertColumnSelectorToMultiColumnSelector({ name: "foo" });
29
10
  expect(result).toHaveLength(1);
30
11
  expect(result[0].name).toEqual([{ type: "regex", value: "foo" }]);
31
12
  });
32
13
 
33
14
  test("passes through array of selectors", () => {
34
- const result = normalizeSelectors([{ name: "a" }, { name: "b" }]);
15
+ const result = convertColumnSelectorToMultiColumnSelector([{ name: "a" }, { name: "b" }]);
35
16
  expect(result).toHaveLength(2);
36
17
  });
37
18
 
38
19
  test("normalizes plain string name to RegexMatcher[]", () => {
39
- const [sel] = normalizeSelectors({ name: "foo" });
20
+ const [sel] = convertColumnSelectorToMultiColumnSelector({ name: "foo" });
40
21
  expect(sel.name).toEqual([{ type: "regex", value: "foo" }]);
41
22
  });
42
23
 
43
24
  test("normalizes array of mixed strings and matchers", () => {
44
- const [sel] = normalizeSelectors({
25
+ const [sel] = convertColumnSelectorToMultiColumnSelector({
45
26
  name: ["foo", { type: "regex", value: "bar.*" as RegExpString }],
46
27
  });
47
28
  expect(sel.name).toEqual([
@@ -51,22 +32,24 @@ describe("normalizeSelectors", () => {
51
32
  });
52
33
 
53
34
  test("normalizes single StringMatcher object", () => {
54
- const [sel] = normalizeSelectors({ name: { type: "exact", value: "foo" } });
35
+ const [sel] = convertColumnSelectorToMultiColumnSelector({
36
+ name: { type: "exact", value: "foo" },
37
+ });
55
38
  expect(sel.name).toEqual([{ type: "exact", value: "foo" }]);
56
39
  });
57
40
 
58
41
  test("normalizes single ValueType to array", () => {
59
- const [sel] = normalizeSelectors({ type: "Int" });
42
+ const [sel] = convertColumnSelectorToMultiColumnSelector({ type: "Int" });
60
43
  expect(sel.type).toEqual(["Int"]);
61
44
  });
62
45
 
63
46
  test("passes through ValueType array", () => {
64
- const [sel] = normalizeSelectors({ type: ["Int", "Long"] });
47
+ const [sel] = convertColumnSelectorToMultiColumnSelector({ type: ["Int", "Long"] });
65
48
  expect(sel.type).toEqual(["Int", "Long"]);
66
49
  });
67
50
 
68
51
  test("normalizes record with plain string values", () => {
69
- const [sel] = normalizeSelectors({
52
+ const [sel] = convertColumnSelectorToMultiColumnSelector({
70
53
  domain: { "pl7.app/chain": "IGHeavy" },
71
54
  });
72
55
  expect(sel.domain).toEqual({
@@ -75,7 +58,7 @@ describe("normalizeSelectors", () => {
75
58
  });
76
59
 
77
60
  test("normalizes record with mixed array values", () => {
78
- const [sel] = normalizeSelectors({
61
+ const [sel] = convertColumnSelectorToMultiColumnSelector({
79
62
  annotations: { label: ["a", { type: "regex", value: "b.*" as RegExpString }] },
80
63
  });
81
64
  expect(sel.annotations).toEqual({
@@ -87,386 +70,21 @@ describe("normalizeSelectors", () => {
87
70
  });
88
71
 
89
72
  test("normalizes axes", () => {
90
- const [sel] = normalizeSelectors({
73
+ const [sel] = convertColumnSelectorToMultiColumnSelector({
91
74
  axes: [{ name: "axisName", type: "String" }],
92
75
  });
93
76
  expect(sel.axes).toEqual([{ name: [{ type: "regex", value: "axisName" }], type: ["String"] }]);
94
77
  });
95
78
 
96
79
  test("preserves partialAxesMatch", () => {
97
- const [sel] = normalizeSelectors({ partialAxesMatch: false });
80
+ const [sel] = convertColumnSelectorToMultiColumnSelector({ partialAxesMatch: false });
98
81
  expect(sel.partialAxesMatch).toBe(false);
99
82
  });
100
83
 
101
84
  test("omits undefined fields", () => {
102
- const [sel] = normalizeSelectors({ name: "foo" });
85
+ const [sel] = convertColumnSelectorToMultiColumnSelector({ name: "foo" });
103
86
  expect(sel.type).toBeUndefined();
104
87
  expect(sel.domain).toBeUndefined();
105
88
  expect(sel.axes).toBeUndefined();
106
89
  });
107
90
  });
108
-
109
- // --- matchColumn ---
110
-
111
- describe("matchColumn", () => {
112
- describe("name matching", () => {
113
- test("exact name match", () => {
114
- const s = spec({ name: "pl7.app/vdj/sequence" });
115
- const sel: MultiColumnSelector = { name: [{ type: "exact", value: "pl7.app/vdj/sequence" }] };
116
- expect(matchColumn(s, sel)).toBe(true);
117
- });
118
-
119
- test("exact name mismatch", () => {
120
- const s = spec({ name: "pl7.app/vdj/sequence" });
121
- const sel: MultiColumnSelector = { name: [{ type: "exact", value: "pl7.app/vdj/other" }] };
122
- expect(matchColumn(s, sel)).toBe(false);
123
- });
124
-
125
- test("regex name match", () => {
126
- const s = spec({ name: "pl7.app/vdj/sequence" });
127
- const sel: MultiColumnSelector = {
128
- name: [{ type: "regex", value: "pl7\\.app/vdj/.*" as RegExpString }],
129
- };
130
- expect(matchColumn(s, sel)).toBe(true);
131
- });
132
-
133
- test("regex full match required", () => {
134
- const s = spec({ name: "pl7.app/vdj/sequence" });
135
- const sel: MultiColumnSelector = { name: [{ type: "regex", value: "vdj" as RegExpString }] };
136
- expect(matchColumn(s, sel)).toBe(false);
137
- });
138
-
139
- test("OR across name matchers", () => {
140
- const s = spec({ name: "colB" });
141
- const sel: MultiColumnSelector = {
142
- name: [
143
- { type: "exact", value: "colA" },
144
- { type: "exact", value: "colB" },
145
- ],
146
- };
147
- expect(matchColumn(s, sel)).toBe(true);
148
- });
149
- });
150
-
151
- describe("type matching", () => {
152
- test("single type match", () => {
153
- const s = spec({ name: "c", valueType: "Int" });
154
- const sel: MultiColumnSelector = { type: ["Int"] };
155
- expect(matchColumn(s, sel)).toBe(true);
156
- });
157
-
158
- test("type mismatch", () => {
159
- const s = spec({ name: "c", valueType: "String" });
160
- const sel: MultiColumnSelector = { type: ["Int"] };
161
- expect(matchColumn(s, sel)).toBe(false);
162
- });
163
-
164
- test("OR across types", () => {
165
- const s = spec({ name: "c", valueType: "Long" });
166
- const sel: MultiColumnSelector = { type: ["Int", "Long"] };
167
- expect(matchColumn(s, sel)).toBe(true);
168
- });
169
- });
170
-
171
- describe("domain matching", () => {
172
- test("matches column domain", () => {
173
- const s = spec({ name: "c", domain: { chain: "IGHeavy" } });
174
- const sel: MultiColumnSelector = {
175
- domain: { chain: [{ type: "exact", value: "IGHeavy" }] },
176
- };
177
- expect(matchColumn(s, sel)).toBe(true);
178
- });
179
-
180
- test("matches combined domain from axes", () => {
181
- const s = spec({
182
- name: "c",
183
- axesSpec: [
184
- { name: "axis1", type: "String", domain: { chain: "IGHeavy" }, annotations: {} },
185
- ] as PColumnSpec["axesSpec"],
186
- });
187
- const sel: MultiColumnSelector = {
188
- domain: { chain: [{ type: "exact", value: "IGHeavy" }] },
189
- };
190
- expect(matchColumn(s, sel)).toBe(true);
191
- });
192
-
193
- test("domain key missing fails", () => {
194
- const s = spec({ name: "c", domain: {} });
195
- const sel: MultiColumnSelector = {
196
- domain: { chain: [{ type: "exact", value: "IGHeavy" }] },
197
- };
198
- expect(matchColumn(s, sel)).toBe(false);
199
- });
200
-
201
- test("multiple domain keys AND-ed", () => {
202
- const s = spec({ name: "c", domain: { chain: "IGHeavy", species: "human" } });
203
- const sel: MultiColumnSelector = {
204
- domain: {
205
- chain: [{ type: "exact", value: "IGHeavy" }],
206
- species: [{ type: "exact", value: "human" }],
207
- },
208
- };
209
- expect(matchColumn(s, sel)).toBe(true);
210
- });
211
-
212
- test("one domain key mismatch fails", () => {
213
- const s = spec({ name: "c", domain: { chain: "IGHeavy", species: "mouse" } });
214
- const sel: MultiColumnSelector = {
215
- domain: {
216
- chain: [{ type: "exact", value: "IGHeavy" }],
217
- species: [{ type: "exact", value: "human" }],
218
- },
219
- };
220
- expect(matchColumn(s, sel)).toBe(false);
221
- });
222
- });
223
-
224
- describe("annotations matching", () => {
225
- test("exact annotation match", () => {
226
- const s = spec({ name: "c", annotations: { label: "CDR3" } });
227
- const sel: MultiColumnSelector = {
228
- annotations: { label: [{ type: "exact", value: "CDR3" }] },
229
- };
230
- expect(matchColumn(s, sel)).toBe(true);
231
- });
232
-
233
- test("regex annotation match", () => {
234
- const s = spec({ name: "c", annotations: { label: "CDR3-length" } });
235
- const sel: MultiColumnSelector = {
236
- annotations: { label: [{ type: "regex", value: ".*CDR3.*" as RegExpString }] },
237
- };
238
- expect(matchColumn(s, sel)).toBe(true);
239
- });
240
-
241
- test("missing annotation key fails", () => {
242
- const s = spec({ name: "c", annotations: {} });
243
- const sel: MultiColumnSelector = {
244
- annotations: { label: [{ type: "exact", value: "CDR3" }] },
245
- };
246
- expect(matchColumn(s, sel)).toBe(false);
247
- });
248
- });
249
-
250
- describe("axes matching", () => {
251
- const withAxes = (axes: PColumnSpec["axesSpec"]) => spec({ name: "c", axesSpec: axes });
252
-
253
- const axis = (name: string, type: string = "String") =>
254
- ({ name, type, domain: {}, annotations: {} }) as PColumnSpec["axesSpec"][number];
255
-
256
- test("partial match (default) — selector axis found", () => {
257
- const s = withAxes([axis("a1"), axis("a2")]);
258
- const sel: MultiColumnSelector = {
259
- axes: [{ name: [{ type: "exact", value: "a1" }] }],
260
- };
261
- expect(matchColumn(s, sel)).toBe(true);
262
- });
263
-
264
- test("partial match — selector axis not found", () => {
265
- const s = withAxes([axis("a1")]);
266
- const sel: MultiColumnSelector = {
267
- axes: [{ name: [{ type: "exact", value: "missing" }] }],
268
- };
269
- expect(matchColumn(s, sel)).toBe(false);
270
- });
271
-
272
- test("exact match — same count and order", () => {
273
- const s = withAxes([axis("a1"), axis("a2")]);
274
- const sel: MultiColumnSelector = {
275
- axes: [
276
- { name: [{ type: "exact", value: "a1" }] },
277
- { name: [{ type: "exact", value: "a2" }] },
278
- ],
279
- partialAxesMatch: false,
280
- };
281
- expect(matchColumn(s, sel)).toBe(true);
282
- });
283
-
284
- test("exact match — wrong order fails", () => {
285
- const s = withAxes([axis("a1"), axis("a2")]);
286
- const sel: MultiColumnSelector = {
287
- axes: [
288
- { name: [{ type: "exact", value: "a2" }] },
289
- { name: [{ type: "exact", value: "a1" }] },
290
- ],
291
- partialAxesMatch: false,
292
- };
293
- expect(matchColumn(s, sel)).toBe(false);
294
- });
295
-
296
- test("exact match — count mismatch fails", () => {
297
- const s = withAxes([axis("a1"), axis("a2")]);
298
- const sel: MultiColumnSelector = {
299
- axes: [{ name: [{ type: "exact", value: "a1" }] }],
300
- partialAxesMatch: false,
301
- };
302
- expect(matchColumn(s, sel)).toBe(false);
303
- });
304
-
305
- test("axis type matching", () => {
306
- const s = withAxes([axis("a1", "Int")]);
307
- const sel: MultiColumnSelector = {
308
- axes: [{ type: ["Int"] }],
309
- };
310
- expect(matchColumn(s, sel)).toBe(true);
311
- });
312
-
313
- test("axis domain matching", () => {
314
- const a = {
315
- name: "a1",
316
- type: "String",
317
- domain: { k: "v" },
318
- annotations: {},
319
- } as PColumnSpec["axesSpec"][number];
320
- const s = withAxes([a]);
321
- const sel: MultiColumnSelector = {
322
- axes: [{ domain: { k: [{ type: "exact", value: "v" }] } }],
323
- };
324
- expect(matchColumn(s, sel)).toBe(true);
325
- });
326
- });
327
-
328
- describe("AND across fields", () => {
329
- test("all fields must match", () => {
330
- const s = spec({
331
- name: "col1",
332
- valueType: "Int",
333
- annotations: { label: "x" },
334
- });
335
- const sel: MultiColumnSelector = {
336
- name: [{ type: "exact", value: "col1" }],
337
- type: ["Int"],
338
- annotations: { label: [{ type: "exact", value: "x" }] },
339
- };
340
- expect(matchColumn(s, sel)).toBe(true);
341
- });
342
-
343
- test("one field mismatch fails entire selector", () => {
344
- const s = spec({
345
- name: "col1",
346
- valueType: "String",
347
- });
348
- const sel: MultiColumnSelector = {
349
- name: [{ type: "exact", value: "col1" }],
350
- type: ["Int"],
351
- };
352
- expect(matchColumn(s, sel)).toBe(false);
353
- });
354
- });
355
-
356
- test("empty selector matches everything", () => {
357
- const s = spec({ name: "anything", valueType: "Double" });
358
- expect(matchColumn(s, {})).toBe(true);
359
- });
360
- });
361
-
362
- // --- matchColumnSelectors (OR across array) ---
363
-
364
- describe("matchColumnSelectors", () => {
365
- test("matches if any selector matches", () => {
366
- const s = spec({ name: "col2" });
367
- const selectors: MultiColumnSelector[] = [
368
- { name: [{ type: "exact", value: "col1" }] },
369
- { name: [{ type: "exact", value: "col2" }] },
370
- ];
371
- expect(matchColumnSelectors(selectors, s)).toBe(true);
372
- });
373
-
374
- test("no match if none match", () => {
375
- const s = spec({ name: "col3" });
376
- const selectors: MultiColumnSelector[] = [
377
- { name: [{ type: "exact", value: "col1" }] },
378
- { name: [{ type: "exact", value: "col2" }] },
379
- ];
380
- expect(matchColumnSelectors(selectors, s)).toBe(false);
381
- });
382
-
383
- test("empty array matches nothing", () => {
384
- const s = spec({ name: "col1" });
385
- expect(matchColumnSelectors([], s)).toBe(false);
386
- });
387
- });
388
-
389
- // --- columnSelectorsToPredicate ---
390
-
391
- describe("columnSelectorsToPredicate", () => {
392
- test("works with relaxed single selector", () => {
393
- const pred = columnSelectorsToPredicate({ name: "col1" });
394
- expect(pred(spec({ name: "col1" }))).toBe(true);
395
- expect(pred(spec({ name: "col2" }))).toBe(false);
396
- });
397
-
398
- test("works with relaxed array of selectors", () => {
399
- const pred = columnSelectorsToPredicate([{ name: "col1" }, { name: "col2" }]);
400
- expect(pred(spec({ name: "col1" }))).toBe(true);
401
- expect(pred(spec({ name: "col2" }))).toBe(true);
402
- expect(pred(spec({ name: "col3" }))).toBe(false);
403
- });
404
-
405
- test("works with regex in relaxed form", () => {
406
- const pred = columnSelectorsToPredicate({
407
- name: { type: "regex", value: "col[12]" as RegExpString },
408
- });
409
- expect(pred(spec({ name: "col1" }))).toBe(true);
410
- expect(pred(spec({ name: "col2" }))).toBe(true);
411
- expect(pred(spec({ name: "col3" }))).toBe(false);
412
- });
413
-
414
- test("domain filter in relaxed form", () => {
415
- const pred = columnSelectorsToPredicate({
416
- domain: { chain: "IGHeavy" },
417
- });
418
- expect(pred(spec({ name: "c", domain: { chain: "IGHeavy" } }))).toBe(true);
419
- expect(pred(spec({ name: "c", domain: { chain: "IGLight" } }))).toBe(false);
420
- expect(pred(spec({ name: "c" }))).toBe(false);
421
- });
422
- });
423
-
424
- // --- Integration: relaxed selectors end-to-end ---
425
-
426
- describe("relaxed selectors end-to-end", () => {
427
- test("design doc example: name + domain relaxed", () => {
428
- const input: RelaxedColumnSelector = {
429
- name: "pl7.app/vdj/sequence",
430
- domain: { "pl7.app/vdj/chain": "IGHeavy" },
431
- };
432
- const [sel] = normalizeSelectors(input);
433
- const s = spec({
434
- name: "pl7.app/vdj/sequence",
435
- domain: { "pl7.app/vdj/chain": "IGHeavy" },
436
- });
437
- expect(matchColumn(s, sel)).toBe(true);
438
- });
439
-
440
- test("design doc example: two selectors OR-ed", () => {
441
- const input: RelaxedColumnSelector[] = [
442
- { name: "pl7.app/vdj/sequence" },
443
- { name: "pl7.app/vdj/geneHit", domain: { "pl7.app/vdj/chain": "IGHeavy" } },
444
- ];
445
- const selectors = normalizeSelectors(input);
446
-
447
- expect(matchColumnSelectors(selectors, spec({ name: "pl7.app/vdj/sequence" }))).toBe(true);
448
-
449
- expect(
450
- matchColumnSelectors(
451
- selectors,
452
- spec({ name: "pl7.app/vdj/geneHit", domain: { "pl7.app/vdj/chain": "IGHeavy" } }),
453
- ),
454
- ).toBe(true);
455
-
456
- expect(
457
- matchColumnSelectors(
458
- selectors,
459
- spec({ name: "pl7.app/vdj/geneHit", domain: { "pl7.app/vdj/chain": "IGLight" } }),
460
- ),
461
- ).toBe(false);
462
- });
463
-
464
- test("design doc example: domain key with multiple values", () => {
465
- const pred = columnSelectorsToPredicate({
466
- domain: { "pl7.app/vdj/chain": ["IGHeavy", "IGLight"] },
467
- });
468
- expect(pred(spec({ name: "c", domain: { "pl7.app/vdj/chain": "IGHeavy" } }))).toBe(true);
469
- expect(pred(spec({ name: "c", domain: { "pl7.app/vdj/chain": "IGLight" } }))).toBe(true);
470
- expect(pred(spec({ name: "c", domain: { "pl7.app/vdj/chain": "TRA" } }))).toBe(false);
471
- });
472
- });
@@ -3,7 +3,6 @@ import type {
3
3
  ColumnValueType,
4
4
  MultiAxisSelector,
5
5
  MultiColumnSelector,
6
- PColumnSpec,
7
6
  StringMatcher,
8
7
  } from "@milaboratories/pl-model-common";
9
8
 
@@ -38,7 +37,7 @@ export interface RelaxedColumnSelector {
38
37
  }
39
38
 
40
39
  /** Input that normalizes to ColumnSelector[]. */
41
- export type ColumnSelectorInput = RelaxedColumnSelector | RelaxedColumnSelector[];
40
+ export type ColumnSelector = RelaxedColumnSelector | RelaxedColumnSelector[];
42
41
 
43
42
  // --- Normalization ---
44
43
 
@@ -64,7 +63,9 @@ function normalizeTypes<T>(input: T | T[]): T[] {
64
63
 
65
64
  type Mutable<T> = { -readonly [K in keyof T]: T[K] };
66
65
 
67
- function normalizeAxisSelector(input: RelaxedAxisSelector): MultiAxisSelector {
66
+ export function convertRelaxedAxisSelectorToMultiAxisSelector(
67
+ input: RelaxedAxisSelector,
68
+ ): MultiAxisSelector {
68
69
  const result: Mutable<MultiAxisSelector> = {};
69
70
  if (input.name !== undefined) result.name = normalizeStringMatchers(input.name);
70
71
  if (input.type !== undefined) result.type = normalizeTypes(input.type);
@@ -75,13 +76,9 @@ function normalizeAxisSelector(input: RelaxedAxisSelector): MultiAxisSelector {
75
76
  return result;
76
77
  }
77
78
 
78
- /** Normalize relaxed input to strict ColumnSelector[]. */
79
- export function normalizeSelectors(input: ColumnSelectorInput): MultiColumnSelector[] {
80
- const arr = Array.isArray(input) ? input : [input];
81
- return arr.map(normalizeSingleSelector);
82
- }
83
-
84
- function normalizeSingleSelector(input: RelaxedColumnSelector): MultiColumnSelector {
79
+ export function convertRelaxedColumnSelectorToMultiColumnSelector(
80
+ input: RelaxedColumnSelector,
81
+ ): MultiColumnSelector {
85
82
  const result: Mutable<MultiColumnSelector> = {};
86
83
  if (input.name !== undefined) result.name = normalizeStringMatchers(input.name);
87
84
  if (input.type !== undefined) result.type = normalizeTypes(input.type);
@@ -89,125 +86,15 @@ function normalizeSingleSelector(input: RelaxedColumnSelector): MultiColumnSelec
89
86
  if (input.contextDomain !== undefined)
90
87
  result.contextDomain = normalizeRecord(input.contextDomain);
91
88
  if (input.annotations !== undefined) result.annotations = normalizeRecord(input.annotations);
92
- if (input.axes !== undefined) result.axes = input.axes.map(normalizeAxisSelector);
89
+ if (input.axes !== undefined)
90
+ result.axes = input.axes.map(convertRelaxedAxisSelectorToMultiAxisSelector);
93
91
  if (input.partialAxesMatch !== undefined) result.partialAxesMatch = input.partialAxesMatch;
94
92
  return result;
95
93
  }
96
94
 
97
- // --- Matching ---
98
-
99
- function matchStringValue(value: string, matchers: StringMatcher[]): boolean {
100
- return matchers.some((m) => {
101
- if (m.type === "exact") return value === m.value;
102
- return new RegExp(`^(?:${m.value})$`).test(value);
103
- });
104
- }
105
-
106
- function matchRecordField(
107
- actual: Record<string, string> | undefined,
108
- required: Record<string, StringMatcher[]>,
109
- ): boolean {
110
- const record = actual ?? {};
111
- for (const [key, matchers] of Object.entries(required)) {
112
- const value = record[key];
113
- if (value === undefined) return false;
114
- if (!matchStringValue(value, matchers)) return false;
115
- }
116
- return true;
117
- }
118
-
119
- /** Get combined domain: column's own domain merged with all axis domains. */
120
- function getCombinedDomain(spec: PColumnSpec): Record<string, string> {
121
- const result: Record<string, string> = {};
122
- if (spec.domain) Object.assign(result, spec.domain);
123
- for (const axis of spec.axesSpec) {
124
- if (axis.domain) Object.assign(result, axis.domain);
125
- }
126
- return result;
127
- }
128
-
129
- /** Get combined context domain: column's own contextDomain merged with all axis contextDomains. */
130
- function getCombinedContextDomain(spec: PColumnSpec): Record<string, string> {
131
- const result: Record<string, string> = {};
132
- if (spec.contextDomain) Object.assign(result, spec.contextDomain);
133
- for (const axis of spec.axesSpec) {
134
- if ("contextDomain" in axis && axis.contextDomain) Object.assign(result, axis.contextDomain);
135
- }
136
- return result;
137
- }
138
-
139
- function matchAxisSelector(
140
- axis: PColumnSpec["axesSpec"][number],
141
- selector: MultiAxisSelector,
142
- ): boolean {
143
- if (selector.name !== undefined && !matchStringValue(axis.name, selector.name)) return false;
144
- if (selector.type !== undefined && !selector.type.includes(axis.type)) return false;
145
- if (selector.domain !== undefined && !matchRecordField(axis.domain, selector.domain))
146
- return false;
147
- if (
148
- selector.contextDomain !== undefined &&
149
- !matchRecordField(
150
- "contextDomain" in axis ? (axis.contextDomain as Record<string, string>) : undefined,
151
- selector.contextDomain,
152
- )
153
- )
154
- return false;
155
- if (
156
- selector.annotations !== undefined &&
157
- !matchRecordField(axis.annotations, selector.annotations)
158
- )
159
- return false;
160
- return true;
161
- }
162
-
163
- /** Check if a PColumnSpec matches a single strict ColumnSelector. */
164
- export function matchColumn(spec: PColumnSpec, selector: MultiColumnSelector): boolean {
165
- if (selector.name !== undefined && !matchStringValue(spec.name, selector.name)) return false;
166
- if (selector.type !== undefined && !selector.type.includes(spec.valueType)) return false;
167
-
168
- if (selector.domain !== undefined) {
169
- const combined = getCombinedDomain(spec);
170
- if (!matchRecordField(combined, selector.domain)) return false;
171
- }
172
-
173
- if (selector.contextDomain !== undefined) {
174
- const combined = getCombinedContextDomain(spec);
175
- if (!matchRecordField(combined, selector.contextDomain)) return false;
176
- }
177
-
178
- if (selector.annotations !== undefined) {
179
- if (!matchRecordField(spec.annotations, selector.annotations)) return false;
180
- }
181
-
182
- if (selector.axes !== undefined) {
183
- const partialMatch = selector.partialAxesMatch ?? true;
184
- if (partialMatch) {
185
- for (const axisSel of selector.axes) {
186
- if (!spec.axesSpec.some((axis) => matchAxisSelector(axis, axisSel))) return false;
187
- }
188
- } else {
189
- if (spec.axesSpec.length !== selector.axes.length) return false;
190
- for (let i = 0; i < selector.axes.length; i++) {
191
- if (!matchAxisSelector(spec.axesSpec[i], selector.axes[i])) return false;
192
- }
193
- }
194
- }
195
-
196
- return true;
197
- }
198
-
199
- /** Check if a PColumnSpec matches any of the selectors (OR across array). */
200
- export function matchColumnSelectors(selectors: MultiColumnSelector[], spec: PColumnSpec): boolean {
201
- return selectors.some((sel) => matchColumn(spec, sel));
202
- }
203
-
204
- /**
205
- * Convert selector input to a predicate function.
206
- * Normalizes relaxed form, then returns a function that OR-matches.
207
- */
208
- export function columnSelectorsToPredicate(
209
- input: ColumnSelectorInput,
210
- ): (spec: PColumnSpec) => boolean {
211
- const selectors = normalizeSelectors(input);
212
- return (spec) => matchColumnSelectors(selectors, spec);
95
+ export function convertColumnSelectorToMultiColumnSelector(
96
+ input: ColumnSelector,
97
+ ): MultiColumnSelector[] {
98
+ const arr = Array.isArray(input) ? input : [input];
99
+ return arr.map(convertRelaxedColumnSelectorToMultiColumnSelector);
213
100
  }
@@ -1,4 +1,4 @@
1
- import type { PColumnSpec, PObjectId } from "@milaboratories/pl-model-common";
1
+ import type { PColumnSpec, PObjectId, SUniversalPColumnId } from "@milaboratories/pl-model-common";
2
2
  import type { PColumnDataUniversal } from "../render/internal";
3
3
 
4
4
  // --- ColumnSnapshot ---
@@ -13,7 +13,7 @@ export type ColumnDataStatus = "ready" | "computing" | "absent";
13
13
  * - `data` holds an active object when data exists (ready or computing),
14
14
  * or `undefined` when data is permanently absent.
15
15
  */
16
- export interface ColumnSnapshot<Id extends PObjectId = PObjectId> {
16
+ export interface ColumnSnapshot<Id extends PObjectId | SUniversalPColumnId> {
17
17
  readonly id: Id;
18
18
  readonly spec: PColumnSpec;
19
19
  readonly dataStatus: ColumnDataStatus;
@@ -45,11 +45,11 @@ export function createReadyColumnData(getData: () => PColumnDataUniversal | unde
45
45
  // --- Snapshot construction helpers ---
46
46
 
47
47
  /** Creates a ColumnSnapshot from parts. */
48
- export function createColumnSnapshot<Id extends PObjectId = PObjectId>(
48
+ export function createColumnSnapshot<Id extends PObjectId>(
49
49
  id: Id,
50
50
  spec: PColumnSpec,
51
+ data: undefined | ColumnData,
51
52
  dataStatus: ColumnDataStatus,
52
- data: ColumnData | undefined,
53
53
  ): ColumnSnapshot<Id> {
54
- return { id, spec, dataStatus, data };
54
+ return { id, spec, data, dataStatus };
55
55
  }