@platforma-sdk/model 1.58.5 → 1.58.9

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 (365) hide show
  1. package/dist/_virtual/_rolldown/runtime.cjs +43 -0
  2. package/dist/_virtual/_rolldown/runtime.js +18 -0
  3. package/dist/annotations/converter.cjs +15 -20
  4. package/dist/annotations/converter.cjs.map +1 -1
  5. package/dist/annotations/converter.d.ts +6 -2
  6. package/dist/annotations/converter.js +14 -18
  7. package/dist/annotations/converter.js.map +1 -1
  8. package/dist/annotations/index.cjs +1 -0
  9. package/dist/annotations/index.d.ts +2 -3
  10. package/dist/annotations/index.js +1 -0
  11. package/dist/annotations/types.d.ts +21 -16
  12. package/dist/bconfig/index.cjs +2 -0
  13. package/dist/bconfig/index.d.ts +5 -6
  14. package/dist/bconfig/index.js +2 -0
  15. package/dist/bconfig/lambdas.d.ts +52 -52
  16. package/dist/bconfig/normalization.cjs +13 -18
  17. package/dist/bconfig/normalization.cjs.map +1 -1
  18. package/dist/bconfig/normalization.d.ts +10 -6
  19. package/dist/bconfig/normalization.js +12 -16
  20. package/dist/bconfig/normalization.js.map +1 -1
  21. package/dist/bconfig/types.cjs +4 -3
  22. package/dist/bconfig/types.cjs.map +1 -1
  23. package/dist/bconfig/types.d.ts +10 -5
  24. package/dist/bconfig/types.js +4 -2
  25. package/dist/bconfig/types.js.map +1 -1
  26. package/dist/bconfig/util.d.ts +7 -4
  27. package/dist/bconfig/v3.d.ts +10 -6
  28. package/dist/block_api_v1.d.ts +62 -58
  29. package/dist/block_api_v2.d.ts +51 -47
  30. package/dist/block_api_v3.d.ts +33 -29
  31. package/dist/block_migrations.cjs +481 -413
  32. package/dist/block_migrations.cjs.map +1 -1
  33. package/dist/block_migrations.d.ts +258 -204
  34. package/dist/block_migrations.js +482 -408
  35. package/dist/block_migrations.js.map +1 -1
  36. package/dist/block_model.cjs +312 -343
  37. package/dist/block_model.cjs.map +1 -1
  38. package/dist/block_model.d.ts +143 -147
  39. package/dist/block_model.js +312 -341
  40. package/dist/block_model.js.map +1 -1
  41. package/dist/block_model_legacy.cjs +231 -255
  42. package/dist/block_model_legacy.cjs.map +1 -1
  43. package/dist/block_model_legacy.d.ts +108 -106
  44. package/dist/block_model_legacy.js +231 -253
  45. package/dist/block_model_legacy.js.map +1 -1
  46. package/dist/block_state_patch.d.ts +10 -10
  47. package/dist/block_state_util.cjs +15 -19
  48. package/dist/block_state_util.cjs.map +1 -1
  49. package/dist/block_state_util.d.ts +14 -13
  50. package/dist/block_state_util.js +15 -18
  51. package/dist/block_state_util.js.map +1 -1
  52. package/dist/block_storage.cjs +233 -238
  53. package/dist/block_storage.cjs.map +1 -1
  54. package/dist/block_storage.d.ts +62 -78
  55. package/dist/block_storage.js +234 -237
  56. package/dist/block_storage.js.map +1 -1
  57. package/dist/block_storage_callbacks.cjs +156 -195
  58. package/dist/block_storage_callbacks.cjs.map +1 -1
  59. package/dist/block_storage_callbacks.js +156 -192
  60. package/dist/block_storage_callbacks.js.map +1 -1
  61. package/dist/block_storage_facade.cjs +29 -85
  62. package/dist/block_storage_facade.cjs.map +1 -1
  63. package/dist/block_storage_facade.d.ts +83 -126
  64. package/dist/block_storage_facade.js +29 -83
  65. package/dist/block_storage_facade.js.map +1 -1
  66. package/dist/components/PFrameForGraphs.cjs +26 -24
  67. package/dist/components/PFrameForGraphs.cjs.map +1 -1
  68. package/dist/components/PFrameForGraphs.d.ts +12 -7
  69. package/dist/components/PFrameForGraphs.js +25 -22
  70. package/dist/components/PFrameForGraphs.js.map +1 -1
  71. package/dist/components/PlAnnotations/filter.d.ts +62 -79
  72. package/dist/components/PlAnnotations/filters_ui.cjs +135 -171
  73. package/dist/components/PlAnnotations/filters_ui.cjs.map +1 -1
  74. package/dist/components/PlAnnotations/filters_ui.d.ts +48 -46
  75. package/dist/components/PlAnnotations/filters_ui.js +135 -170
  76. package/dist/components/PlAnnotations/filters_ui.js.map +1 -1
  77. package/dist/components/PlAnnotations/index.d.ts +2 -3
  78. package/dist/components/PlDataTable/index.cjs +2 -0
  79. package/dist/components/PlDataTable/index.d.ts +3 -5
  80. package/dist/components/PlDataTable/index.js +2 -0
  81. package/dist/components/PlDataTable/labels.cjs +59 -81
  82. package/dist/components/PlDataTable/labels.cjs.map +1 -1
  83. package/dist/components/PlDataTable/labels.js +58 -79
  84. package/dist/components/PlDataTable/labels.js.map +1 -1
  85. package/dist/components/PlDataTable/state-migration.cjs +186 -144
  86. package/dist/components/PlDataTable/state-migration.cjs.map +1 -1
  87. package/dist/components/PlDataTable/state-migration.d.ts +85 -82
  88. package/dist/components/PlDataTable/state-migration.js +185 -142
  89. package/dist/components/PlDataTable/state-migration.js.map +1 -1
  90. package/dist/components/PlDataTable/table.cjs +172 -194
  91. package/dist/components/PlDataTable/table.cjs.map +1 -1
  92. package/dist/components/PlDataTable/table.d.ts +16 -12
  93. package/dist/components/PlDataTable/table.js +171 -192
  94. package/dist/components/PlDataTable/table.js.map +1 -1
  95. package/dist/components/PlDataTable/v4.d.ts +84 -119
  96. package/dist/components/PlDataTable/v5.d.ts +80 -103
  97. package/dist/components/PlMultiSequenceAlignment.cjs +27 -29
  98. package/dist/components/PlMultiSequenceAlignment.cjs.map +1 -1
  99. package/dist/components/PlMultiSequenceAlignment.d.ts +36 -27
  100. package/dist/components/PlMultiSequenceAlignment.js +26 -27
  101. package/dist/components/PlMultiSequenceAlignment.js.map +1 -1
  102. package/dist/components/PlSelectionModel.cjs +7 -6
  103. package/dist/components/PlSelectionModel.cjs.map +1 -1
  104. package/dist/components/PlSelectionModel.d.ts +10 -8
  105. package/dist/components/PlSelectionModel.js +7 -5
  106. package/dist/components/PlSelectionModel.js.map +1 -1
  107. package/dist/components/index.cjs +8 -0
  108. package/dist/components/index.d.ts +11 -6
  109. package/dist/components/index.js +8 -0
  110. package/dist/config/actions.cjs +138 -171
  111. package/dist/config/actions.cjs.map +1 -1
  112. package/dist/config/actions.d.ts +47 -47
  113. package/dist/config/actions.js +146 -178
  114. package/dist/config/actions.js.map +1 -1
  115. package/dist/config/actions_kinds.d.ts +114 -121
  116. package/dist/config/index.cjs +1 -0
  117. package/dist/config/index.d.ts +6 -7
  118. package/dist/config/index.js +1 -0
  119. package/dist/config/model.d.ts +131 -127
  120. package/dist/config/model_meta.d.ts +4 -1
  121. package/dist/config/type_engine.d.ts +22 -21
  122. package/dist/config/type_util.d.ts +12 -10
  123. package/dist/env_value.cjs +5 -6
  124. package/dist/env_value.cjs.map +1 -1
  125. package/dist/env_value.d.ts +4 -1
  126. package/dist/env_value.js +5 -5
  127. package/dist/env_value.js.map +1 -1
  128. package/dist/filters/converters/filterToQuery.cjs +273 -239
  129. package/dist/filters/converters/filterToQuery.cjs.map +1 -1
  130. package/dist/filters/converters/filterToQuery.d.ts +6 -2
  131. package/dist/filters/converters/filterToQuery.js +272 -237
  132. package/dist/filters/converters/filterToQuery.js.map +1 -1
  133. package/dist/filters/converters/filterUiToExpressionImpl.cjs +56 -85
  134. package/dist/filters/converters/filterUiToExpressionImpl.cjs.map +1 -1
  135. package/dist/filters/converters/filterUiToExpressionImpl.d.ts +8 -4
  136. package/dist/filters/converters/filterUiToExpressionImpl.js +55 -83
  137. package/dist/filters/converters/filterUiToExpressionImpl.js.map +1 -1
  138. package/dist/filters/converters/index.cjs +2 -0
  139. package/dist/filters/converters/index.d.ts +2 -3
  140. package/dist/filters/converters/index.js +2 -0
  141. package/dist/filters/distill.cjs +59 -60
  142. package/dist/filters/distill.cjs.map +1 -1
  143. package/dist/filters/distill.d.ts +6 -3
  144. package/dist/filters/distill.js +58 -58
  145. package/dist/filters/distill.js.map +1 -1
  146. package/dist/filters/index.cjs +4 -0
  147. package/dist/filters/index.d.ts +5 -4
  148. package/dist/filters/index.js +4 -0
  149. package/dist/filters/traverse.cjs +31 -40
  150. package/dist/filters/traverse.cjs.map +1 -1
  151. package/dist/filters/traverse.js +31 -39
  152. package/dist/filters/traverse.js.map +1 -1
  153. package/dist/filters/types.d.ts +10 -7
  154. package/dist/index.cjs +193 -187
  155. package/dist/index.d.ts +61 -28
  156. package/dist/index.js +49 -41
  157. package/dist/internal.cjs +48 -62
  158. package/dist/internal.cjs.map +1 -1
  159. package/dist/internal.js +49 -60
  160. package/dist/internal.js.map +1 -1
  161. package/dist/package.cjs +12 -0
  162. package/dist/package.cjs.map +1 -0
  163. package/dist/package.js +6 -0
  164. package/dist/package.js.map +1 -0
  165. package/dist/pframe.cjs +32 -37
  166. package/dist/pframe.cjs.map +1 -1
  167. package/dist/pframe.d.ts +14 -10
  168. package/dist/pframe.js +32 -35
  169. package/dist/pframe.js.map +1 -1
  170. package/dist/pframe_utils/axes.cjs +81 -114
  171. package/dist/pframe_utils/axes.cjs.map +1 -1
  172. package/dist/pframe_utils/axes.d.ts +10 -13
  173. package/dist/pframe_utils/axes.js +80 -112
  174. package/dist/pframe_utils/axes.js.map +1 -1
  175. package/dist/pframe_utils/columns.cjs +61 -81
  176. package/dist/pframe_utils/columns.cjs.map +1 -1
  177. package/dist/pframe_utils/columns.d.ts +15 -6
  178. package/dist/pframe_utils/columns.js +60 -79
  179. package/dist/pframe_utils/columns.js.map +1 -1
  180. package/dist/pframe_utils/index.cjs +232 -253
  181. package/dist/pframe_utils/index.cjs.map +1 -1
  182. package/dist/pframe_utils/index.d.ts +39 -35
  183. package/dist/pframe_utils/index.js +231 -251
  184. package/dist/pframe_utils/index.js.map +1 -1
  185. package/dist/platforma.d.ts +48 -46
  186. package/dist/plugin_handle.cjs +6 -14
  187. package/dist/plugin_handle.cjs.map +1 -1
  188. package/dist/plugin_handle.d.ts +20 -25
  189. package/dist/plugin_handle.js +6 -13
  190. package/dist/plugin_handle.js.map +1 -1
  191. package/dist/plugin_model.cjs +364 -163
  192. package/dist/plugin_model.cjs.map +1 -1
  193. package/dist/plugin_model.d.ts +280 -129
  194. package/dist/plugin_model.js +362 -163
  195. package/dist/plugin_model.js.map +1 -1
  196. package/dist/raw_globals.cjs +10 -22
  197. package/dist/raw_globals.cjs.map +1 -1
  198. package/dist/raw_globals.d.ts +8 -5
  199. package/dist/raw_globals.js +10 -20
  200. package/dist/raw_globals.js.map +1 -1
  201. package/dist/ref_util.cjs +14 -13
  202. package/dist/ref_util.cjs.map +1 -1
  203. package/dist/ref_util.d.ts +18 -12
  204. package/dist/ref_util.js +14 -11
  205. package/dist/ref_util.js.map +1 -1
  206. package/dist/render/accessor.cjs +213 -226
  207. package/dist/render/accessor.cjs.map +1 -1
  208. package/dist/render/accessor.d.ts +115 -120
  209. package/dist/render/accessor.js +212 -224
  210. package/dist/render/accessor.js.map +1 -1
  211. package/dist/render/api.cjs +478 -580
  212. package/dist/render/api.cjs.map +1 -1
  213. package/dist/render/api.d.ts +207 -209
  214. package/dist/render/api.js +476 -578
  215. package/dist/render/api.js.map +1 -1
  216. package/dist/render/future.cjs +28 -32
  217. package/dist/render/future.cjs.map +1 -1
  218. package/dist/render/future.d.ts +15 -11
  219. package/dist/render/future.js +28 -30
  220. package/dist/render/future.js.map +1 -1
  221. package/dist/render/index.cjs +8 -0
  222. package/dist/render/index.d.ts +10 -8
  223. package/dist/render/index.js +8 -0
  224. package/dist/render/internal.cjs +33 -29
  225. package/dist/render/internal.cjs.map +1 -1
  226. package/dist/render/internal.d.ts +78 -72
  227. package/dist/render/internal.js +29 -26
  228. package/dist/render/internal.js.map +1 -1
  229. package/dist/render/traversal_ops.d.ts +42 -43
  230. package/dist/render/util/axis_filtering.cjs +63 -86
  231. package/dist/render/util/axis_filtering.cjs.map +1 -1
  232. package/dist/render/util/axis_filtering.d.ts +10 -7
  233. package/dist/render/util/axis_filtering.js +63 -85
  234. package/dist/render/util/axis_filtering.js.map +1 -1
  235. package/dist/render/util/column_collection.cjs +266 -321
  236. package/dist/render/util/column_collection.cjs.map +1 -1
  237. package/dist/render/util/column_collection.d.ts +47 -47
  238. package/dist/render/util/column_collection.js +264 -319
  239. package/dist/render/util/column_collection.js.map +1 -1
  240. package/dist/render/util/index.cjs +4 -0
  241. package/dist/render/util/index.d.ts +4 -5
  242. package/dist/render/util/index.js +4 -0
  243. package/dist/render/util/label.cjs +129 -163
  244. package/dist/render/util/label.cjs.map +1 -1
  245. package/dist/render/util/label.d.ts +45 -46
  246. package/dist/render/util/label.js +128 -161
  247. package/dist/render/util/label.js.map +1 -1
  248. package/dist/render/util/pcolumn_data.cjs +315 -375
  249. package/dist/render/util/pcolumn_data.cjs.map +1 -1
  250. package/dist/render/util/pcolumn_data.d.ts +33 -32
  251. package/dist/render/util/pcolumn_data.js +314 -373
  252. package/dist/render/util/pcolumn_data.js.map +1 -1
  253. package/dist/render/util/pframe_upgraders.cjs +37 -42
  254. package/dist/render/util/pframe_upgraders.cjs.map +1 -1
  255. package/dist/render/util/pframe_upgraders.js +37 -41
  256. package/dist/render/util/pframe_upgraders.js.map +1 -1
  257. package/dist/render/util/split_selectors.d.ts +13 -9
  258. package/dist/version.cjs +6 -8
  259. package/dist/version.cjs.map +1 -1
  260. package/dist/version.d.ts +7 -4
  261. package/dist/version.js +5 -5
  262. package/dist/version.js.map +1 -1
  263. package/package.json +10 -4
  264. package/src/block_migrations.test.ts +184 -14
  265. package/src/block_migrations.ts +185 -30
  266. package/src/block_model.ts +111 -66
  267. package/src/block_storage.test.ts +147 -3
  268. package/src/block_storage.ts +43 -8
  269. package/src/block_storage_callbacks.ts +9 -4
  270. package/src/env_value.ts +0 -2
  271. package/src/index.ts +12 -11
  272. package/src/internal.ts +0 -1
  273. package/src/platforma.ts +4 -4
  274. package/src/plugin_handle.ts +1 -1
  275. package/src/plugin_model.test.ts +217 -21
  276. package/src/plugin_model.ts +450 -55
  277. package/src/raw_globals.ts +0 -1
  278. package/dist/annotations/converter.d.ts.map +0 -1
  279. package/dist/annotations/index.d.ts.map +0 -1
  280. package/dist/annotations/types.d.ts.map +0 -1
  281. package/dist/bconfig/index.d.ts.map +0 -1
  282. package/dist/bconfig/lambdas.d.ts.map +0 -1
  283. package/dist/bconfig/normalization.d.ts.map +0 -1
  284. package/dist/bconfig/types.d.ts.map +0 -1
  285. package/dist/bconfig/util.d.ts.map +0 -1
  286. package/dist/bconfig/v3.d.ts.map +0 -1
  287. package/dist/block_api_v1.d.ts.map +0 -1
  288. package/dist/block_api_v2.d.ts.map +0 -1
  289. package/dist/block_api_v3.d.ts.map +0 -1
  290. package/dist/block_migrations.d.ts.map +0 -1
  291. package/dist/block_model.d.ts.map +0 -1
  292. package/dist/block_model_legacy.d.ts.map +0 -1
  293. package/dist/block_state_patch.d.ts.map +0 -1
  294. package/dist/block_state_util.d.ts.map +0 -1
  295. package/dist/block_storage.d.ts.map +0 -1
  296. package/dist/block_storage_callbacks.d.ts +0 -115
  297. package/dist/block_storage_callbacks.d.ts.map +0 -1
  298. package/dist/block_storage_facade.d.ts.map +0 -1
  299. package/dist/components/PFrameForGraphs.d.ts.map +0 -1
  300. package/dist/components/PlAnnotations/filter.d.ts.map +0 -1
  301. package/dist/components/PlAnnotations/filters_ui.d.ts.map +0 -1
  302. package/dist/components/PlAnnotations/index.d.ts.map +0 -1
  303. package/dist/components/PlAnnotations/types.d.ts +0 -3
  304. package/dist/components/PlAnnotations/types.d.ts.map +0 -1
  305. package/dist/components/PlDataTable/index.d.ts.map +0 -1
  306. package/dist/components/PlDataTable/labels.d.ts +0 -7
  307. package/dist/components/PlDataTable/labels.d.ts.map +0 -1
  308. package/dist/components/PlDataTable/state-migration.d.ts.map +0 -1
  309. package/dist/components/PlDataTable/table.d.ts.map +0 -1
  310. package/dist/components/PlDataTable/v4.d.ts.map +0 -1
  311. package/dist/components/PlDataTable/v5.d.ts.map +0 -1
  312. package/dist/components/PlMultiSequenceAlignment.d.ts.map +0 -1
  313. package/dist/components/PlSelectionModel.d.ts.map +0 -1
  314. package/dist/components/index.d.ts.map +0 -1
  315. package/dist/config/actions.d.ts.map +0 -1
  316. package/dist/config/actions_kinds.d.ts.map +0 -1
  317. package/dist/config/index.d.ts.map +0 -1
  318. package/dist/config/model.d.ts.map +0 -1
  319. package/dist/config/model_meta.d.ts.map +0 -1
  320. package/dist/config/type_engine.d.ts.map +0 -1
  321. package/dist/config/type_util.d.ts.map +0 -1
  322. package/dist/env_value.d.ts.map +0 -1
  323. package/dist/filters/converters/filterToQuery.d.ts.map +0 -1
  324. package/dist/filters/converters/filterUiToExpressionImpl.d.ts.map +0 -1
  325. package/dist/filters/converters/index.d.ts.map +0 -1
  326. package/dist/filters/distill.d.ts.map +0 -1
  327. package/dist/filters/index.d.ts.map +0 -1
  328. package/dist/filters/traverse.d.ts +0 -27
  329. package/dist/filters/traverse.d.ts.map +0 -1
  330. package/dist/filters/types.d.ts.map +0 -1
  331. package/dist/index.cjs.map +0 -1
  332. package/dist/index.d.ts.map +0 -1
  333. package/dist/index.js.map +0 -1
  334. package/dist/internal.d.ts +0 -36
  335. package/dist/internal.d.ts.map +0 -1
  336. package/dist/package.json.cjs +0 -6
  337. package/dist/package.json.cjs.map +0 -1
  338. package/dist/package.json.js +0 -4
  339. package/dist/package.json.js.map +0 -1
  340. package/dist/pframe.d.ts.map +0 -1
  341. package/dist/pframe_utils/axes.d.ts.map +0 -1
  342. package/dist/pframe_utils/columns.d.ts.map +0 -1
  343. package/dist/pframe_utils/index.d.ts.map +0 -1
  344. package/dist/pframe_utils/querySpec.d.ts +0 -2
  345. package/dist/pframe_utils/querySpec.d.ts.map +0 -1
  346. package/dist/platforma.d.ts.map +0 -1
  347. package/dist/plugin_handle.d.ts.map +0 -1
  348. package/dist/plugin_model.d.ts.map +0 -1
  349. package/dist/raw_globals.d.ts.map +0 -1
  350. package/dist/ref_util.d.ts.map +0 -1
  351. package/dist/render/accessor.d.ts.map +0 -1
  352. package/dist/render/api.d.ts.map +0 -1
  353. package/dist/render/future.d.ts.map +0 -1
  354. package/dist/render/index.d.ts.map +0 -1
  355. package/dist/render/internal.d.ts.map +0 -1
  356. package/dist/render/traversal_ops.d.ts.map +0 -1
  357. package/dist/render/util/axis_filtering.d.ts.map +0 -1
  358. package/dist/render/util/column_collection.d.ts.map +0 -1
  359. package/dist/render/util/index.d.ts.map +0 -1
  360. package/dist/render/util/label.d.ts.map +0 -1
  361. package/dist/render/util/pcolumn_data.d.ts.map +0 -1
  362. package/dist/render/util/pframe_upgraders.d.ts +0 -3
  363. package/dist/render/util/pframe_upgraders.d.ts.map +0 -1
  364. package/dist/render/util/split_selectors.d.ts.map +0 -1
  365. package/dist/version.d.ts.map +0 -1
@@ -1,10 +1,15 @@
1
1
  import { describe, expect, it } from "vitest";
2
- import { DataModelBuilder, defaultRecover, makeDataVersioned } from "./block_migrations";
2
+ import {
3
+ DataModelBuilder,
4
+ defaultRecover,
5
+ makeVersionedData,
6
+ type TransferTarget,
7
+ } from "./block_migrations";
3
8
  import { DATA_MODEL_LEGACY_VERSION } from "./block_storage";
4
9
 
5
- describe("makeDataVersioned", () => {
10
+ describe("makeVersionedData", () => {
6
11
  it("creates correct DataVersioned shape", () => {
7
- const versioned = makeDataVersioned("v1", { count: 42 });
12
+ const versioned = makeVersionedData("v1", { count: 42 });
8
13
  expect(versioned).toStrictEqual({ version: "v1", data: { count: 42 } });
9
14
  });
10
15
  });
@@ -16,7 +21,7 @@ describe("DataModel migrations", () => {
16
21
  .migrate<{ count: number; label: string }>("v2", (v1) => ({ ...v1, label: "" }))
17
22
  .init(() => ({ count: 0, label: "" }));
18
23
 
19
- const result = dataModel.migrate(makeDataVersioned("legacy", { count: 42 }));
24
+ const result = dataModel.migrate(makeVersionedData("legacy", { count: 42 }));
20
25
  expect(result.version).toBe("v2");
21
26
  expect(result.data).toStrictEqual({ count: 0, label: "" });
22
27
  });
@@ -42,7 +47,7 @@ describe("DataModel migrations", () => {
42
47
  })
43
48
  .init(() => ({ numbers: [], label: "" }));
44
49
 
45
- expect(() => dataModel.migrate(makeDataVersioned("v1", { numbers: [666] }))).toThrow(
50
+ expect(() => dataModel.migrate(makeVersionedData("v1", { numbers: [666] }))).toThrow(
46
51
  "Forbidden number",
47
52
  );
48
53
  });
@@ -66,7 +71,7 @@ describe("DataModel migrations", () => {
66
71
  .init(() => ({ count: 0, label: "" }));
67
72
 
68
73
  // Legacy data is recovered as V1 then goes through v1→v2 migration
69
- const result = dataModel.migrate(makeDataVersioned("legacy", { count: 5 }));
74
+ const result = dataModel.migrate(makeVersionedData("legacy", { count: 5 }));
70
75
  expect(result.version).toBe("v2");
71
76
  expect(result.data).toStrictEqual({ count: 5, label: "default" });
72
77
  });
@@ -92,7 +97,7 @@ describe("DataModel migrations", () => {
92
97
  .migrate<V3>("v3", (v2) => ({ ...v2, description: "added" }))
93
98
  .init(() => ({ count: 0, label: "", description: "" }));
94
99
 
95
- const result = dataModel.migrate(makeDataVersioned("legacy", { count: 7 }));
100
+ const result = dataModel.migrate(makeVersionedData("legacy", { count: 7 }));
96
101
  expect(result.version).toBe("v3");
97
102
  expect(result.data).toStrictEqual({ count: 7, label: "recovered", description: "added" });
98
103
  });
@@ -116,7 +121,7 @@ describe("DataModel migrations", () => {
116
121
  })
117
122
  .init(() => ({ count: 0, label: "" }));
118
123
 
119
- const result = dataModel.migrate(makeDataVersioned("legacy", { count: 9 }));
124
+ const result = dataModel.migrate(makeVersionedData("legacy", { count: 9 }));
120
125
  expect(result.version).toBe("v2");
121
126
  expect(result.data).toStrictEqual({ count: 9, label: "recovered" });
122
127
  });
@@ -128,7 +133,7 @@ describe("DataModel migrations", () => {
128
133
  .recover((version, data) => defaultRecover(version, data))
129
134
  .init(() => ({ count: 0, label: "" }));
130
135
 
131
- const result = dataModel.migrate(makeDataVersioned("unknown", { count: 7 }));
136
+ const result = dataModel.migrate(makeVersionedData("unknown", { count: 7 }));
132
137
  expect(result.version).toBe("v2");
133
138
  expect(result.data).toStrictEqual({ count: 0, label: "" });
134
139
  });
@@ -156,7 +161,7 @@ describe("DataModel migrations", () => {
156
161
  })
157
162
  .init(() => ({ count: 0, label: "", description: "" }));
158
163
 
159
- const result = dataModel.migrate(makeDataVersioned("legacy", { count: 7 }));
164
+ const result = dataModel.migrate(makeVersionedData("legacy", { count: 7 }));
160
165
  expect(result.version).toBe("v3");
161
166
  expect(result.data).toStrictEqual({ count: 0, label: "", description: "" });
162
167
  });
@@ -184,7 +189,7 @@ describe("DataModel migrations", () => {
184
189
 
185
190
  // Legacy data arrives at DATA_MODEL_LEGACY_VERSION (how normalizeBlockStorage wraps it)
186
191
  const result = dataModel.migrate(
187
- makeDataVersioned(DATA_MODEL_LEGACY_VERSION, {
192
+ makeVersionedData(DATA_MODEL_LEGACY_VERSION, {
188
193
  args: { inputFile: "test.fa", threshold: 5 },
189
194
  uiState: { selectedTab: "results" },
190
195
  }),
@@ -209,7 +214,7 @@ describe("DataModel migrations", () => {
209
214
 
210
215
  // Non-legacy data at the user's version passes through unchanged
211
216
  const result = dataModel.migrate(
212
- makeDataVersioned("v1", {
217
+ makeVersionedData("v1", {
213
218
  inputFile: "existing.fa",
214
219
  threshold: 10,
215
220
  selectedTab: "overview",
@@ -237,7 +242,7 @@ describe("DataModel migrations", () => {
237
242
  .init(() => ({ inputFile: "", threshold: 0, selectedTab: "main", description: "" }));
238
243
 
239
244
  const result = dataModel.migrate(
240
- makeDataVersioned(DATA_MODEL_LEGACY_VERSION, {
245
+ makeVersionedData(DATA_MODEL_LEGACY_VERSION, {
241
246
  args: { inputFile: "test.fa", threshold: 3 },
242
247
  uiState: { selectedTab: "tab1" },
243
248
  }),
@@ -261,7 +266,7 @@ describe("DataModel migrations", () => {
261
266
 
262
267
  expect(() =>
263
268
  dataModel.migrate(
264
- makeDataVersioned(DATA_MODEL_LEGACY_VERSION, {
269
+ makeVersionedData(DATA_MODEL_LEGACY_VERSION, {
265
270
  args: { inputFile: "test.fa", threshold: 5 },
266
271
  uiState: { selectedTab: "results" },
267
272
  }),
@@ -269,4 +274,169 @@ describe("DataModel migrations", () => {
269
274
  ).toThrow("bad legacy data");
270
275
  });
271
276
  });
277
+
278
+ describe("transfer()", () => {
279
+ // Helper: create a TransferTarget with given id and transferVersion
280
+ function makeTarget<Id extends string>(
281
+ id: Id,
282
+ transferVersion = "tv1",
283
+ ): TransferTarget<Id, unknown> {
284
+ return { id, transferVersion } as TransferTarget<Id, unknown>;
285
+ }
286
+
287
+ it("captures data at the current chain position via migrate()", () => {
288
+ type V1 = { count: number; tableState: string };
289
+ type V2 = { count: number };
290
+ const tableTarget = makeTarget("table1", "pv1");
291
+
292
+ const dataModel = new DataModelBuilder()
293
+ .from<V1>("v1")
294
+ .transfer(tableTarget, (v1) => ({ state: v1.tableState }))
295
+ .migrate<V2>("v2", ({ tableState: _, ...rest }) => rest)
296
+ .init(() => ({ count: 0 }));
297
+
298
+ const result = dataModel.migrate(
299
+ makeVersionedData("v1", { count: 5, tableState: "expanded" }),
300
+ );
301
+
302
+ expect(result.version).toBe("v2");
303
+ expect(result.data).toStrictEqual({ count: 5 });
304
+ expect(result.transfers).toHaveProperty("table1");
305
+ expect(result.transfers["table1"].data).toStrictEqual({ state: "expanded" });
306
+ expect(result.transfers["table1"].version).toBe("pv1");
307
+ });
308
+
309
+ it("captures data after last migration step when transfer is at the end", () => {
310
+ type V1 = { count: number };
311
+ type V2 = { count: number; label: string };
312
+ const target = makeTarget("endPlugin");
313
+
314
+ const dataModel = new DataModelBuilder()
315
+ .from<V1>("v1")
316
+ .migrate<V2>("v2", (v1) => ({ ...v1, label: "added" }))
317
+ .transfer(target, (v2) => ({ snapshot: v2.label }))
318
+ .init(() => ({ count: 0, label: "" }));
319
+
320
+ const result = dataModel.migrate(makeVersionedData("v1", { count: 1 }));
321
+
322
+ expect(result.version).toBe("v2");
323
+ expect(result.transfers["endPlugin"].data).toStrictEqual({ snapshot: "added" });
324
+ });
325
+
326
+ it("collects multiple transfers at different chain positions", () => {
327
+ type V1 = { a: number; b: string };
328
+ type V2 = { a: number };
329
+ type V3 = { a: number; c: boolean };
330
+ const target1 = makeTarget("plugin1");
331
+ const target2 = makeTarget("plugin2");
332
+
333
+ const dataModel = new DataModelBuilder()
334
+ .from<V1>("v1")
335
+ .transfer(target1, (v1) => ({ fromB: v1.b }))
336
+ .migrate<V2>("v2", ({ b: _, ...rest }) => rest)
337
+ .transfer(target2, (v2) => ({ fromA: v2.a }))
338
+ .migrate<V3>("v3", (v2) => ({ ...v2, c: true }))
339
+ .init(() => ({ a: 0, c: false }));
340
+
341
+ const result = dataModel.migrate(makeVersionedData("v1", { a: 42, b: "hello" }));
342
+
343
+ expect(result.data).toStrictEqual({ a: 42, c: true });
344
+ expect(result.transfers["plugin1"].data).toStrictEqual({ fromB: "hello" });
345
+ expect(result.transfers["plugin2"].data).toStrictEqual({ fromA: 42 });
346
+ });
347
+
348
+ it("migrate() still works unchanged (ignores transfers)", () => {
349
+ type V1 = { count: number; tableState: string };
350
+ type V2 = { count: number };
351
+ const tableTarget = makeTarget("table1");
352
+
353
+ const dataModel = new DataModelBuilder()
354
+ .from<V1>("v1")
355
+ .transfer(tableTarget, (v1) => ({ state: v1.tableState }))
356
+ .migrate<V2>("v2", ({ tableState: _, ...rest }) => rest)
357
+ .init(() => ({ count: 0 }));
358
+
359
+ const result = dataModel.migrate(
360
+ makeVersionedData("v1", { count: 5, tableState: "expanded" }),
361
+ );
362
+
363
+ expect(result.version).toBe("v2");
364
+ expect(result.data).toStrictEqual({ count: 5 });
365
+ });
366
+
367
+ it("returns empty transfers on fast-path (already at latest version)", () => {
368
+ type V1 = { count: number };
369
+ const target = makeTarget("s1");
370
+
371
+ const dataModel = new DataModelBuilder()
372
+ .from<V1>("v1")
373
+ .transfer(target, (v1) => ({ x: v1.count }))
374
+ .init(() => ({ count: 0 }));
375
+
376
+ const result = dataModel.migrate(makeVersionedData("v1", { count: 7 }));
377
+
378
+ expect(result.data).toStrictEqual({ count: 7 });
379
+ expect(result.transfers).toStrictEqual({});
380
+ });
381
+
382
+ it("returns empty transfers on recovery path", () => {
383
+ type V1 = { count: number };
384
+ type V2 = { count: number; label: string };
385
+ const target = makeTarget("s1");
386
+
387
+ const dataModel = new DataModelBuilder()
388
+ .from<V1>("v1")
389
+ .transfer(target, (v1) => ({ x: v1.count }))
390
+ .migrate<V2>("v2", (v1) => ({ ...v1, label: "" }))
391
+ .recover((_version, _data) => defaultRecover(_version, _data))
392
+ .init(() => ({ count: 0, label: "" }));
393
+
394
+ const result = dataModel.migrate(makeVersionedData("unknown", { count: 99 }));
395
+
396
+ // Recovery resets to initial data
397
+ expect(result.data).toStrictEqual({ count: 0, label: "" });
398
+ expect(result.transfers).toStrictEqual({});
399
+ });
400
+
401
+ it("rejects duplicate transfer plugin IDs at runtime", () => {
402
+ const target = makeTarget("dup");
403
+
404
+ expect(() => {
405
+ new DataModelBuilder()
406
+ .from<{ a: number }>("v1")
407
+ .transfer(target, (v1) => v1.a)
408
+ .transfer(target, (v1) => v1.a);
409
+ }).toThrow(/duplicate/i);
410
+ });
411
+
412
+ it("transfer with upgradeLegacy — transfer fires after upgrade step", () => {
413
+ type LegacyArgs = { inputFile: string };
414
+ type LegacyUiState = { tab: string };
415
+ type V1 = { inputFile: string; tab: string };
416
+ type V2 = { inputFile: string };
417
+ const target = makeTarget("tabPlugin", "pv1");
418
+
419
+ const dataModel = new DataModelBuilder()
420
+ .from<V1>("v1")
421
+ .upgradeLegacy<LegacyArgs, LegacyUiState>(({ args, uiState }) => ({
422
+ inputFile: args.inputFile,
423
+ tab: uiState.tab,
424
+ }))
425
+ .transfer(target, (v1) => ({ tab: v1.tab }))
426
+ .migrate<V2>("v2", ({ tab: _, ...rest }) => rest)
427
+ .init(() => ({ inputFile: "" }));
428
+
429
+ const result = dataModel.migrate(
430
+ makeVersionedData(DATA_MODEL_LEGACY_VERSION, {
431
+ args: { inputFile: "test.fa" },
432
+ uiState: { tab: "results" },
433
+ }),
434
+ );
435
+
436
+ expect(result.version).toBe("v2");
437
+ expect(result.data).toStrictEqual({ inputFile: "test.fa" });
438
+ expect(result.transfers["tabPlugin"].data).toStrictEqual({ tab: "results" });
439
+ expect(result.transfers["tabPlugin"].version).toBe("pv1");
440
+ });
441
+ });
272
442
  });