@ryuzaki13/react-foundation-ui 1.8.5 → 1.8.7

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 (312) hide show
  1. package/dist/advanced-search/index.js +2 -2
  2. package/dist/base-table/index.js +1 -1
  3. package/dist/chunks/{base-table-CsnUiMTe.js → base-table-CYbtifH0.js} +2 -2
  4. package/dist/chunks/{base-table-CsnUiMTe.js.map → base-table-CYbtifH0.js.map} +1 -1
  5. package/dist/chunks/{context-menu-C8sA7xCN.js → context-menu-L4KM0FRD.js} +2 -2
  6. package/dist/chunks/{context-menu-C8sA7xCN.js.map → context-menu-L4KM0FRD.js.map} +1 -1
  7. package/dist/chunks/date-input-g6l1iDmf.js.map +1 -1
  8. package/dist/chunks/{multi-select-Cvjz9W07.js → multi-select-CCgoTHWI.js} +2 -2
  9. package/dist/chunks/{multi-select-Cvjz9W07.js.map → multi-select-CCgoTHWI.js.map} +1 -1
  10. package/dist/chunks/{picker-0I1yMKIY.js → picker-Cb3D2Hts.js} +6 -2
  11. package/dist/chunks/picker-Cb3D2Hts.js.map +1 -0
  12. package/dist/chunks/{select-CUQ91FIc.js → select-Baek-IUe.js} +2 -2
  13. package/dist/chunks/{select-CUQ91FIc.js.map → select-Baek-IUe.js.map} +1 -1
  14. package/dist/chunks/{table-z9kyd9U3.js → table-CrQiurtA.js} +2 -2
  15. package/dist/chunks/{table-z9kyd9U3.js.map → table-CrQiurtA.js.map} +1 -1
  16. package/dist/context-menu/index.js +1 -1
  17. package/dist/layout-picker/index.js +1 -1
  18. package/dist/listbox/index.js +1 -1
  19. package/dist/multi-select/index.js +1 -1
  20. package/dist/picker/index.js +1 -1
  21. package/dist/preset-select/index.js +1 -1
  22. package/dist/select/index.js +1 -1
  23. package/dist/simple-table/index.js +1 -1
  24. package/dist/slider/index.js +1 -1
  25. package/dist/state-select/index.js +1 -1
  26. package/dist/styles.css +1 -1
  27. package/dist/table/index.js +1 -1
  28. package/dist/table-sorting/index.js +1 -1
  29. package/dist/tree-select/index.js +1 -1
  30. package/dist/tree-table/index.js +1 -1
  31. package/package.json +4 -4
  32. package/storybook-static/assets/{Badge-CzxxuE7D.js → Badge-C4U4sxtF.js} +1 -1
  33. package/storybook-static/assets/{Badge.stories-RaI7qvpZ.js → Badge.stories-DHmJTpdf.js} +1 -1
  34. package/storybook-static/assets/{BadgeList-B7cF3h_F.js → BadgeList-BOs5ycWn.js} +1 -1
  35. package/storybook-static/assets/{Button-Cjmm8oDV.js → Button-BTtYeCS_.js} +1 -1
  36. package/storybook-static/assets/{Button-6z1R7ZA8.js → Button-Bkb3wQw6.js} +1 -1
  37. package/storybook-static/assets/{Button.stories-B5fUA2Gu.js → Button.stories-DgFLAdcg.js} +1 -1
  38. package/storybook-static/assets/{CalendarView-Dlt0f4Jr.js → CalendarView-BIFHbOTr.js} +1 -1
  39. package/storybook-static/assets/{CheckBox-L4324ZCs.js → CheckBox-76M-N56J.js} +1 -1
  40. package/storybook-static/assets/{CheckBox-BOSDcvCd.js → CheckBox-D4u-58g8.js} +1 -1
  41. package/storybook-static/assets/{CheckBox.module-CoYygdZx.js → CheckBox.module-BOAVN-Ny.js} +1 -1
  42. package/storybook-static/assets/{CheckBox.stories-DALRNTV0.js → CheckBox.stories-Caw6-hSQ.js} +1 -1
  43. package/storybook-static/assets/{Color-6AOWCN3U-UmlmbwVs.js → Color-6AOWCN3U-CPYGaU3y.js} +1 -1
  44. package/storybook-static/assets/{ContextMenu-giZ56GIC.js → ContextMenu-CUWt-eg1.js} +1 -1
  45. package/storybook-static/assets/{ContextMenu-BOez7LwB.js → ContextMenu-gfYYiVdR.js} +1 -1
  46. package/storybook-static/assets/{ContextMenu.stories-BnoaSq3Q.js → ContextMenu.stories-BuQS57wW.js} +1 -1
  47. package/storybook-static/assets/{CustomOptionButton-C1VgtQgI.js → CustomOptionButton-Be7sd0Lb.js} +1 -1
  48. package/storybook-static/assets/{DateInput-A3468S6P.js → DateInput-B4oviF7J.js} +1 -1
  49. package/storybook-static/assets/{DateInput-oWtyLo3Q.js → DateInput-BQGUMYsW.js} +1 -1
  50. package/storybook-static/assets/{DateInput.stories-BeGG7Vzf.js → DateInput.stories-D6q7J1C4.js} +1 -1
  51. package/storybook-static/assets/{DateRangePresetSelect--h5MdeWg.js → DateRangePresetSelect-BAxaG0HP.js} +1 -1
  52. package/storybook-static/assets/{DateRangePresetSelect-DbKRsjNX.js → DateRangePresetSelect-Cq6pOZPu.js} +1 -1
  53. package/storybook-static/assets/{DateRangePresetSelect.stories-BS1ll9RK.js → DateRangePresetSelect.stories-d4HFbao6.js} +1 -1
  54. package/storybook-static/assets/{Detail-FEi6FSkD.js → Detail-DlETcWVp.js} +1 -1
  55. package/storybook-static/assets/{Detail.stories-Dy2yKBDx.js → Detail.stories-BEwFXEZH.js} +1 -1
  56. package/storybook-static/assets/{Dialog-C7Zfcyjf.js → Dialog-Bk8aoiOf.js} +1 -1
  57. package/storybook-static/assets/{Dialog-CXnHtk_h.js → Dialog-D63TJr1M.js} +1 -1
  58. package/storybook-static/assets/{Dialog.stories-BeUqdA_f.js → Dialog.stories-BR7NqeZj.js} +1 -1
  59. package/storybook-static/assets/{Disclosure-BqsgTrM0.js → Disclosure-zQK54WKU.js} +1 -1
  60. package/storybook-static/assets/{Disclosure.stories-D3LzXhet.js → Disclosure.stories-CNLpB5YJ.js} +1 -1
  61. package/storybook-static/assets/{DisclosureGroup-BAF5Untb.js → DisclosureGroup-C_nZSLZw.js} +1 -1
  62. package/storybook-static/assets/{DocsRenderer-JROSPFPF-luRRUpJ_.js → DocsRenderer-JROSPFPF-CoU8mWAw.js} +2 -2
  63. package/storybook-static/assets/{DropZone-B-YA4zyu.js → DropZone-CUz1Q4bA.js} +1 -1
  64. package/storybook-static/assets/{DropZone-DKrOIaeH.js → DropZone-Y5hvED_x.js} +1 -1
  65. package/storybook-static/assets/{DropZone.stories-wf2ubfGc.js → DropZone.stories-BH4FSM4P.js} +1 -1
  66. package/storybook-static/assets/{DropdownMenu-BiWUESj0.js → DropdownMenu-Bi6-5Gqf.js} +1 -1
  67. package/storybook-static/assets/{ExpandableActionPanel-Dtfw5TWs.js → ExpandableActionPanel-BfWj887r.js} +1 -1
  68. package/storybook-static/assets/{ExpandableActionPanel.stories-BOdw0CLN.js → ExpandableActionPanel.stories-CGxcwRMU.js} +1 -1
  69. package/storybook-static/assets/{Flex-BaSYiAMD.js → Flex-Dm-Qfvzk.js} +1 -1
  70. package/storybook-static/assets/{Flex.stories-CD_e9R5B.js → Flex.stories-B3zMz03s.js} +1 -1
  71. package/storybook-static/assets/{FlexContainer-LmZIdhq2.js → FlexContainer-BWyPlTMB.js} +1 -1
  72. package/storybook-static/assets/{FlexItem-vkDYa5tA.js → FlexItem-pu3E11Sf.js} +1 -1
  73. package/storybook-static/assets/{FloatingPopover-C65hSmop.js → FloatingPopover-NMRTnqfo.js} +1 -1
  74. package/storybook-static/assets/FormattedTableCell-BISjHrBJ.js +15 -0
  75. package/storybook-static/assets/{Grid-BCzygAqy.js → Grid-CzO0Ae1r.js} +1 -1
  76. package/storybook-static/assets/{Grid-8eLmW2AB.js → Grid-vZyA-712.js} +1 -1
  77. package/storybook-static/assets/{Grid.stories-DULQOmbC.js → Grid.stories-BQqK0zom.js} +1 -1
  78. package/storybook-static/assets/{GridContainer-qDguE1HS.js → GridContainer-fKYgDsLl.js} +1 -1
  79. package/storybook-static/assets/{ImageCropper.stories-C1O-Zv4X.js → ImageCropper.stories-Ca4MZWOW.js} +3 -3
  80. package/storybook-static/assets/{ImageRenderer-BOyGnl1v.js → ImageRenderer-BWIk_76e.js} +1 -1
  81. package/storybook-static/assets/{ImageRenderer.stories-Cms0kMXA.js → ImageRenderer.stories-C1FfOcFD.js} +1 -1
  82. package/storybook-static/assets/{ImageView.stories-CUR6bAyn.js → ImageView.stories-DyuR7kdq.js} +1 -1
  83. package/storybook-static/assets/{ImageViewer.stories-BwJKAIT7.js → ImageViewer.stories-PcvOFYqC.js} +2 -2
  84. package/storybook-static/assets/{ImageViewerRuntime-CzkvEHax.js → ImageViewerRuntime-BiI7Xukq.js} +2 -2
  85. package/storybook-static/assets/{Input-B2_RznVE.js → Input-CsD-x1BQ.js} +1 -1
  86. package/storybook-static/assets/{Input-ebp78QN1.js → Input-D_4GoCLl.js} +1 -1
  87. package/storybook-static/assets/{Input.stories-BKwTRsUL.js → Input.stories-D-1urO1N.js} +1 -1
  88. package/storybook-static/assets/{InputDateTime-pK4mlxxm.js → InputDateTime-CFQanHxB.js} +1 -1
  89. package/storybook-static/assets/{InputDateTime.stories-J4Gd0DaU.js → InputDateTime.stories-Q4Ao5Tat.js} +1 -1
  90. package/storybook-static/assets/{InputFile-D1x1T--f.js → InputFile-Bj8PXGY3.js} +1 -1
  91. package/storybook-static/assets/{InputFile-BYcgJx2f.js → InputFile-DM6fBXUx.js} +1 -1
  92. package/storybook-static/assets/{InputFile.stories-DAYDiSFH.js → InputFile.stories-DC27BYoQ.js} +1 -1
  93. package/storybook-static/assets/{InputFiles-D7kcGvWK.js → InputFiles-D59MGS0Z.js} +1 -1
  94. package/storybook-static/assets/{InputFiles-C9HH7fIG.js → InputFiles-teFj6f6X.js} +1 -1
  95. package/storybook-static/assets/{InputFiles.stories-CJTwQutb.js → InputFiles.stories-DX5UEvYR.js} +1 -1
  96. package/storybook-static/assets/{InputFilesList-ChI0hQ07.js → InputFilesList-BD4Y0gN-.js} +1 -1
  97. package/storybook-static/assets/{InputImage-B3KFrWqa.js → InputImage-DmsFGNLJ.js} +1 -1
  98. package/storybook-static/assets/{InputImage-C0-U_QHU.js → InputImage-Du6jGDmY.js} +1 -1
  99. package/storybook-static/assets/{InputImage.stories-QEtqeok5.js → InputImage.stories-u0hrr-Da.js} +1 -1
  100. package/storybook-static/assets/{InteractiveComponents-DB71eb-1.js → InteractiveComponents-BLQiSO3p.js} +1 -1
  101. package/storybook-static/assets/{InteractiveComponents.stories-DdZpmMis.js → InteractiveComponents.stories-BxIVvRz5.js} +1 -1
  102. package/storybook-static/assets/{LayoutPicker-CicZY4X9.js → LayoutPicker-TecE4x6w.js} +1 -1
  103. package/storybook-static/assets/{LayoutPicker-DBEYC_LA.js → LayoutPicker-xUooYcbS.js} +1 -1
  104. package/storybook-static/assets/{LayoutPicker.stories-BFtP0gOy.js → LayoutPicker.stories-YDMnmhJ4.js} +1 -1
  105. package/storybook-static/assets/{Listbox-B0Nqys9f.js → Listbox-D2k8QfTs.js} +1 -1
  106. package/storybook-static/assets/{Listbox-CLP0Cpin.js → Listbox-DplAn6ND.js} +1 -1
  107. package/storybook-static/assets/{Listbox.stories-BHeIn0H8.js → Listbox.stories-Bg3_UQD4.js} +1 -1
  108. package/storybook-static/assets/{Modal-D4jDp5U4.js → Modal-4OdkCwCv.js} +1 -1
  109. package/storybook-static/assets/{Modal.stories-CMHJdaj1.js → Modal.stories-BwawDSGR.js} +1 -1
  110. package/storybook-static/assets/{ModalManagerProvider-D8tCMe07.js → ModalManagerProvider-CYR_xbpx.js} +1 -1
  111. package/storybook-static/assets/{MultiSelect-Bmb0qTzT.js → MultiSelect-CXn1CY9G.js} +1 -1
  112. package/storybook-static/assets/{MultiSelect-y6FjtCjy.js → MultiSelect-iwbCRD9H.js} +1 -1
  113. package/storybook-static/assets/{MultiSelect.stories-B9TZNWng.js → MultiSelect.stories-BSjAL2ua.js} +1 -1
  114. package/storybook-static/assets/{NoData-CzlhZzHI.js → NoData-6Scjk2OD.js} +1 -1
  115. package/storybook-static/assets/{NotificationsHost-AE9gk5zq.js → NotificationsHost-DK3A-iq7.js} +1 -1
  116. package/storybook-static/assets/{NotificationsHost.stories-Bu0__u38.js → NotificationsHost.stories-BRmPf9Q7.js} +1 -1
  117. package/storybook-static/assets/{ODataMultiSelect-DJ6zie6W.js → ODataMultiSelect-CuNGV1QU.js} +1 -1
  118. package/storybook-static/assets/{ODataMultiSelect.stories-BjgJGbWL.js → ODataMultiSelect.stories-CyAonfZC.js} +1 -1
  119. package/storybook-static/assets/{ODataSelect-V1JJpKB9.js → ODataSelect-vhh4NJS_.js} +1 -1
  120. package/storybook-static/assets/{ODataSelect.stories-B2INiDvW.js → ODataSelect.stories-aJBFF45H.js} +1 -1
  121. package/storybook-static/assets/{ODataTreeMultiSelect-BKMrgz8e.js → ODataTreeMultiSelect-vPtlTloF.js} +1 -1
  122. package/storybook-static/assets/{ODataTreeMultiSelect.stories-CjLPeqio.js → ODataTreeMultiSelect.stories-DTBAF628.js} +1 -1
  123. package/storybook-static/assets/{ODataTreeSelect-C2iGJdYk.js → ODataTreeSelect-BCVVLB9M.js} +1 -1
  124. package/storybook-static/assets/{ODataTreeSelect.stories-ReyoXlcX.js → ODataTreeSelect.stories-CptC0p6O.js} +1 -1
  125. package/storybook-static/assets/{OneStepScroller-knlVIvl2.js → OneStepScroller-DerjCiL3.js} +1 -1
  126. package/storybook-static/assets/{Option-CJBK9i2B.css → Option-CwetjUM8.css} +1 -1
  127. package/storybook-static/assets/{Option-KVcu4DcX.js → Option-DkAw9S3l.js} +4 -4
  128. package/storybook-static/assets/{OptionButton-D2ZcZtPU.js → OptionButton-CGurT23Z.js} +1 -1
  129. package/storybook-static/assets/{PeriodSelect-BsET8TST.js → PeriodSelect-DOO139ke.js} +1 -1
  130. package/storybook-static/assets/{PeriodSelect-Bm_VPE_5.js → PeriodSelect-TrGTMIid.js} +1 -1
  131. package/storybook-static/assets/{PeriodSelect.stories-Due2DawD.js → PeriodSelect.stories-B3GEgBZ1.js} +1 -1
  132. package/storybook-static/assets/{PickerTriggerActions-KgIZBVSt.js → PickerTriggerActions-CKVPuKEC.js} +1 -1
  133. package/storybook-static/assets/{Popover-Cq1q1mW3.js → Popover-BNItmUQ9.js} +1 -1
  134. package/storybook-static/assets/{Popover-D38IExq9.js → Popover-DgXqO0PN.js} +1 -1
  135. package/storybook-static/assets/{Popover.stories-B5MXPFi2.js → Popover.stories-bX5S41pH.js} +1 -1
  136. package/storybook-static/assets/{PresetRangeDateInput-dWe-Zcrb.js → PresetRangeDateInput-B4FYPy8g.js} +1 -1
  137. package/storybook-static/assets/{PresetRangeDateInput-C4iOgcKK.js → PresetRangeDateInput-GSnnpZzy.js} +1 -1
  138. package/storybook-static/assets/{PresetRangeDateInput.stories-C8JiJCpi.js → PresetRangeDateInput.stories-Ca0mIo33.js} +1 -1
  139. package/storybook-static/assets/{PresetSelect-CIqamiLP.js → PresetSelect-B_KRl4SQ.js} +1 -1
  140. package/storybook-static/assets/README-1RIcD7RV.js +694 -0
  141. package/storybook-static/assets/README-B1XUsXZj.js +334 -0
  142. package/storybook-static/assets/README-BH78sIZ_.js +288 -0
  143. package/storybook-static/assets/README-BgeYwR6t.js +347 -0
  144. package/storybook-static/assets/README-BhsUMTSk.js +860 -0
  145. package/storybook-static/assets/README-Bj88Ecb7.js +876 -0
  146. package/storybook-static/assets/README-C9saKIyr.js +417 -0
  147. package/storybook-static/assets/README-CP1S4LYF.js +1309 -0
  148. package/storybook-static/assets/README-Cc-guFb0.js +1487 -0
  149. package/storybook-static/assets/README-CheO0E1A.js +282 -0
  150. package/storybook-static/assets/README-CiuVVUgE.js +420 -0
  151. package/storybook-static/assets/README-CvRg9lqh.js +273 -0
  152. package/storybook-static/assets/README-DCdV2RQL.js +1093 -0
  153. package/storybook-static/assets/README-DyNQqotW.js +338 -0
  154. package/storybook-static/assets/README-W1rhe8Sk.js +648 -0
  155. package/storybook-static/assets/{RadioButton-CTA-WBmG.js → RadioButton-CA9DN5bY.js} +1 -1
  156. package/storybook-static/assets/{RadioButton-DfRRX6Id.js → RadioButton-DcXbcFW1.js} +1 -1
  157. package/storybook-static/assets/{RadioButton.stories-D6MO9y2H.js → RadioButton.stories-1_kzxnXY.js} +1 -1
  158. package/storybook-static/assets/{RadioGroup-CiEUg_Oc.js → RadioGroup-bEwTHCyS.js} +1 -1
  159. package/storybook-static/assets/{RadioGroup-BAoD6ZDR.js → RadioGroup-mfYgdfXM.js} +1 -1
  160. package/storybook-static/assets/{RadioGroup.stories-CCjYE-3G.js → RadioGroup.stories-CecdqPms.js} +1 -1
  161. package/storybook-static/assets/{Scrollable-ns4PHUAk.js → Scrollable-1fdTDJHK.js} +1 -1
  162. package/storybook-static/assets/{Select-Bj9NxEJa.js → Select-CvQZGS1G.js} +1 -1
  163. package/storybook-static/assets/{Select-D2aDjIb_.js → Select-Df5Md2Cm.js} +1 -1
  164. package/storybook-static/assets/{Select.stories-zErlbrrD.js → Select.stories-M4M80KTq.js} +1 -1
  165. package/storybook-static/assets/{SerializableSelect-P7iNwTbc.js → SerializableSelect-CnsGo9Ep.js} +1 -1
  166. package/storybook-static/assets/{SerializableSelect.stories-DUAK_mo8.js → SerializableSelect.stories-BJ6MlNDx.js} +1 -1
  167. package/storybook-static/assets/{SingleDateTimeInput-vvyw15zU.js → SingleDateTimeInput-BCV0gfB9.js} +1 -1
  168. package/storybook-static/assets/{SingleDateTimeInput-CkMMccYd.js → SingleDateTimeInput-DJH7zSIz.js} +1 -1
  169. package/storybook-static/assets/{SingleDateTimeInput.stories-CSW9M9hH.js → SingleDateTimeInput.stories-DgEwAFe8.js} +1 -1
  170. package/storybook-static/assets/{Slider-Dftgrmfi.js → Slider-D504FPH3.js} +1 -1
  171. package/storybook-static/assets/{Slider-CkUdrb57.js → Slider-cLRAHPLi.js} +1 -1
  172. package/storybook-static/assets/{Slider.stories-zVUgi1Wb.js → Slider.stories-EI314Iff.js} +1 -1
  173. package/storybook-static/assets/{SliderInput-BINdZsru.js → SliderInput-Bt0H8rgN.js} +1 -1
  174. package/storybook-static/assets/{SliderInput-DnVNzY_q.js → SliderInput-E5p3n3VY.js} +1 -1
  175. package/storybook-static/assets/{SliderInput.stories-CfY1B4PZ.js → SliderInput.stories-CDYPq7fP.js} +1 -1
  176. package/storybook-static/assets/{Sortable-BnixGZFs.js → Sortable-Bzd7JK4E.js} +1 -1
  177. package/storybook-static/assets/{Sortable.stories-DFzv9lnf.js → Sortable.stories-DNGbmn2a.js} +1 -1
  178. package/storybook-static/assets/{Splitter-BtDFBrQ3.js → Splitter-DSf48AOW.js} +1 -1
  179. package/storybook-static/assets/{Splitter.stories-CipjzPJH.js → Splitter.stories-DUKsOqNN.js} +1 -1
  180. package/storybook-static/assets/{StateSelect-DagWIbnr.js → StateSelect-BxuKIsLa.js} +1 -1
  181. package/storybook-static/assets/{StateSelect-J5sxWYjq.js → StateSelect-HKOT6kq9.js} +1 -1
  182. package/storybook-static/assets/{StateSelect.stories-DDIqhm2K.js → StateSelect.stories-CbLvq7ou.js} +1 -1
  183. package/storybook-static/assets/{StringToggle.stories-CkYGiOe-.js → StringToggle.stories-DOKL-aWy.js} +1 -1
  184. package/storybook-static/assets/{Switch-B5TS1mrR.js → Switch-CLAfhk73.js} +1 -1
  185. package/storybook-static/assets/{Switch-N-Lxev-q.js → Switch-CVTjSEq1.js} +1 -1
  186. package/storybook-static/assets/{Switch.stories-HNOx5mPv.js → Switch.stories-CL5Xe_HQ.js} +1 -1
  187. package/storybook-static/assets/{Table-DTzmRzDD.js → Table-DKc19RME.js} +1 -1
  188. package/storybook-static/assets/Table.stories-CJ9DR1S-.js +207 -0
  189. package/storybook-static/assets/{Tabs-Bc5dgtoT.js → Tabs-De_4F0H3.js} +1 -1
  190. package/storybook-static/assets/{Tabs.stories-BgLnKKFv.js → Tabs.stories-DPAvvkh9.js} +2 -2
  191. package/storybook-static/assets/{TabsBox-sTVLs8k0.js → TabsBox-Cy5CICcb.js} +1 -1
  192. package/storybook-static/assets/{TagInput-yPLHo0PJ.js → TagInput-7n98ftvD.js} +1 -1
  193. package/storybook-static/assets/{TagInput.stories-B4C-230C.js → TagInput.stories-B6JAb3XA.js} +1 -1
  194. package/storybook-static/assets/{Text-C2-mep6V.js → Text-CjSG8mvD.js} +1 -1
  195. package/storybook-static/assets/{Textarea-bqvYs13v.js → Textarea-CQqwaJ0Q.js} +1 -1
  196. package/storybook-static/assets/{Textarea-B7pXYTGv.js → Textarea-Dea29_yQ.js} +1 -1
  197. package/storybook-static/assets/{Textarea.stories-BSSaqnZI.js → Textarea.stories-BZf3Cu4S.js} +1 -1
  198. package/storybook-static/assets/{TimePanel-pMBlR0ZN.js → TimePanel-CPZ4jOw2.js} +1 -1
  199. package/storybook-static/assets/{TimePanel.stories-Cn5IEcsV.js → TimePanel.stories-y5Lp9sMG.js} +1 -1
  200. package/storybook-static/assets/{Toggle-E4xV63pY.js → Toggle-CJHzo9mB.js} +1 -1
  201. package/storybook-static/assets/{Toggle-h6ESIcwX.js → Toggle-s7SzQ11W.js} +1 -1
  202. package/storybook-static/assets/{Toggle.stories-9uqFBAAr.js → Toggle.stories-Dk3C5Le5.js} +1 -1
  203. package/storybook-static/assets/{TreeMultiSelect-DBGlliij.js → TreeMultiSelect-CxXF7pQE.js} +1 -1
  204. package/storybook-static/assets/{TreeMultiSelect-J8Tlnv3Y.js → TreeMultiSelect-DfeggvLr.js} +1 -1
  205. package/storybook-static/assets/{TreeMultiSelect.stories-CYDuvIk7.js → TreeMultiSelect.stories-DKiHT_6L.js} +1 -1
  206. package/storybook-static/assets/{TreePickerBase-BswrqgW3.js → TreePickerBase-DKJJDVC_.js} +1 -1
  207. package/storybook-static/assets/{TreeSelect-B1Buti64.js → TreeSelect-2E1KhJMi.js} +1 -1
  208. package/storybook-static/assets/{TreeSelect-Jchj-RXf.js → TreeSelect-h23orAoA.js} +1 -1
  209. package/storybook-static/assets/{TreeSelect.stories-DzCqueCG.js → TreeSelect.stories-DO06yaS0.js} +1 -1
  210. package/storybook-static/assets/{TreeTable-oYCdUTsS.js → TreeTable-ByV2_E0S.js} +1 -1
  211. package/storybook-static/assets/{TreeTable.stories-L4FHah8x.js → TreeTable.stories-D4gbQx59.js} +2 -2
  212. package/storybook-static/assets/{WithTooltip-7X4HQR7L-Cakt_JaX.js → WithTooltip-7X4HQR7L-DQ4Qthn2.js} +1 -1
  213. package/storybook-static/assets/{array-D-_yMMUK-CIRmlF93.js → array-D-_yMMUK-BQ0uu1hZ.js} +1 -1
  214. package/storybook-static/assets/{async-Bsdhj8g_.js → async-BI7SlYp0.js} +1 -1
  215. package/storybook-static/assets/axe-_9eNhXQJ.js +20 -0
  216. package/storybook-static/assets/{blocks-BA_1CXsr.js → blocks-B8F5vBhs.js} +6 -6
  217. package/storybook-static/assets/check-mlY_aVEI.js +1 -0
  218. package/storybook-static/assets/chevron-down-C7c-TcEc.js +1 -0
  219. package/storybook-static/assets/chevron-left-2LrGBhDY.js +1 -0
  220. package/storybook-static/assets/chevron-right-D6NN1_UQ.js +1 -0
  221. package/storybook-static/assets/{chunk-242VQQM5-BMWWiybC.js → chunk-242VQQM5-bHL6qIJq.js} +1 -1
  222. package/storybook-static/assets/{chunk-DRQKCCAG-CqE-Zrl9.js → chunk-DRQKCCAG-DvsmU7ha.js} +1 -1
  223. package/storybook-static/assets/{chunk-IMSF75WX-yvVUwIQZ.js → chunk-IMSF75WX-CGYlPTyG.js} +1 -1
  224. package/storybook-static/assets/{chunk-KJHJLCBK-D-yQfkOi.js → chunk-KJHJLCBK-yRlRMfNs.js} +1 -1
  225. package/storybook-static/assets/{chunk-QQBDHPVZ-B98qboss.js → chunk-QQBDHPVZ-DC5n6Pix.js} +1 -1
  226. package/storybook-static/assets/{chunk-W22LQPXL-B40Li12y.js → chunk-W22LQPXL-5sD3hVeE.js} +1 -1
  227. package/storybook-static/assets/{circle-alert-C855gqBz.js → circle-alert-H_7GSXFp.js} +1 -1
  228. package/storybook-static/assets/circle-check-B0voRIBT.js +1 -0
  229. package/storybook-static/assets/{components-DSUjzUVy.js → components-Bw-2TeQP.js} +12 -12
  230. package/storybook-static/assets/{contextMenu-DCSPTQNQ.js → contextMenu-B8JusItT.js} +1 -1
  231. package/storybook-static/assets/{createControlledStoryRender-DHsyXc1B.js → createControlledStoryRender-BouhvX-R.js} +1 -1
  232. package/storybook-static/assets/{date-segments-D3HouZ37.js → date-segments-DeoMkKv9.js} +1 -1
  233. package/storybook-static/assets/{defaultRenderers-V5HI39JH.js → defaultRenderers-BHXboKuy.js} +1 -1
  234. package/storybook-static/assets/{dom-B3G_GtJw.js → dom-DBd_DWF8.js} +1 -1
  235. package/storybook-static/assets/{download-B3oJ9vHV.js → download-CSY7aIz0.js} +1 -1
  236. package/storybook-static/assets/{error-BZrNlEUO.js → error-De9R4E_F.js} +1 -1
  237. package/storybook-static/assets/{file-vPGnhPr-.js → file-CwRoWxeB.js} +1 -1
  238. package/storybook-static/assets/floating-ui.react-D7RwPYeO.js +1 -0
  239. package/storybook-static/assets/formatter-L2YTDE3Q-CRGuSxAF.js +1 -0
  240. package/storybook-static/assets/{formatters-CBgrBeSA-DY6OIAc8.js → formatters-CBgrBeSA-CqB1pZxS.js} +1 -1
  241. package/storybook-static/assets/{foundationLib-BFrQ5jez.js → foundationLib-BoYGVeXe.js} +1 -1
  242. package/storybook-static/assets/{hooks-_jPrECht.js → hooks-DQXvhAPr.js} +2 -2
  243. package/storybook-static/assets/iframe-B8PAuhnL.js +1 -0
  244. package/storybook-static/assets/{iframe-Cq8y-8O_.js → iframe-CViB2sFm.js} +23 -23
  245. package/storybook-static/assets/{info-CiT6g2aP.js → info-MrQcS8jn.js} +1 -1
  246. package/storybook-static/assets/{matchers-JIUQ3HVY-DvR2XErZ.js → matchers-JIUQ3HVY-C789_MAK.js} +1 -1
  247. package/storybook-static/assets/{media-BycWpjAl.js → media-D9cE2tzi.js} +1 -1
  248. package/storybook-static/assets/odata-CBGaUmRT.js +1 -0
  249. package/storybook-static/assets/{odata-service-B6TxBSLm-BW9QLSrS.js → odata-service-B6TxBSLm-Bq8Ya67E.js} +1 -1
  250. package/storybook-static/assets/{odataFetchFn-C6ps_31t.js → odataFetchFn-CPO8XIYX.js} +1 -1
  251. package/storybook-static/assets/{odataStoryFixtures-BcNo-Wxr.js → odataStoryFixtures--SWu2yC_.js} +2 -2
  252. package/storybook-static/assets/{persisted-B6h1b3UG.js → persisted-B2dfNRCz.js} +1 -1
  253. package/storybook-static/assets/{preload-helper-BHmFeTtP.js → preload-helper-wdlQj8DP.js} +1 -1
  254. package/storybook-static/assets/react-18-D4o7zN8K.js +9 -0
  255. package/storybook-static/assets/{react-C21x__mS.js → react-BZJXY1be.js} +1 -1
  256. package/storybook-static/assets/{react-qN2cStNd.js → react-Bl2r1tuC.js} +1 -1
  257. package/storybook-static/assets/{react-CvkUhHUq.js → react-GkniIHEK.js} +1 -1
  258. package/storybook-static/assets/{react-dom-2o2phaJG.js → react-dom-BzEl8usk.js} +1 -1
  259. package/storybook-static/assets/react-iQQwtFPL.js +9 -0
  260. package/storybook-static/assets/{refresh-cw-DIeuulxV.js → refresh-cw-_wTFfhR2.js} +1 -1
  261. package/storybook-static/assets/{rolldown-runtime-C0FnF6B9.js → rolldown-runtime-DkW27tQK.js} +1 -1
  262. package/storybook-static/assets/{settings-2-Gfu_uw21.js → settings-2-BqduNJjJ.js} +1 -1
  263. package/storybook-static/assets/{shim-BUMlC1GG.js → shim-DlYORV19.js} +1 -1
  264. package/storybook-static/assets/{sortable-DxRr6Rgq.js → sortable-D-m6SEp7.js} +1 -1
  265. package/storybook-static/assets/syntaxhighlighter-QEQV7K2Y-CEo9I1qZ.js +6 -0
  266. package/storybook-static/assets/{theming-mTWhffkp.js → theming-Cvtrnj7n.js} +1 -1
  267. package/storybook-static/assets/{trash-2-CqKAB1Q0.js → trash-2-65ZF92zp.js} +1 -1
  268. package/storybook-static/assets/{treeStoryFixtures-Ci7STpiz.js → treeStoryFixtures-DXHh9GL3.js} +1 -1
  269. package/storybook-static/assets/{triangle-alert-D4omsgZJ.js → triangle-alert-k_CRNi0k.js} +1 -1
  270. package/storybook-static/assets/{ui.module-D4CuGr8r.js → ui.module-Cat84Nza.js} +1 -1
  271. package/storybook-static/assets/{uiClasses-CVGbL980.js → uiClasses-B9c6dZuu.js} +1 -1
  272. package/storybook-static/assets/{useFlexClasses-Gn9spXEB.js → useFlexClasses-SgVG37Bb.js} +1 -1
  273. package/storybook-static/assets/{useODataSelectBase-DacE6X5d.js → useODataSelectBase-Ck_hduYv.js} +1 -1
  274. package/storybook-static/assets/{useODataTreeData-BEYyje5V.js → useODataTreeData-DTrxPY_k.js} +1 -1
  275. package/storybook-static/assets/usePickerDefaultFilter-5Q1pAV4d.js +1 -0
  276. package/storybook-static/assets/{usePickerQuery-BRsuRnoH.js → usePickerQuery-DdeWtJWc.js} +1 -1
  277. package/storybook-static/assets/{usePickerTriggerController-DyFq40t1.js → usePickerTriggerController-D8hxWmGo.js} +2 -2
  278. package/storybook-static/assets/{utils-DUM89eIj.js → utils-tg3ibbzi.js} +1 -1
  279. package/storybook-static/assets/x-C5XG0bD4.js +1 -0
  280. package/storybook-static/iframe.html +7 -7
  281. package/storybook-static/index.json +1 -1
  282. package/storybook-static/project.json +1 -1
  283. package/storybook-static/sb-addons/chromatic-com-storybook-1/manager-bundle.js +35 -33
  284. package/storybook-static/sb-manager/globals-runtime.js +7 -7
  285. package/storybook-static/sb-manager/globals.js +1 -1
  286. package/storybook-static/sb-manager/runtime.js +88 -89
  287. package/storybook-static/vite-inject-mocker-entry.js +2 -2
  288. package/dist/chunks/picker-0I1yMKIY.js.map +0 -1
  289. package/storybook-static/assets/FormattedTableCell-BdA15EY1.js +0 -15
  290. package/storybook-static/assets/Table.stories-DY5NfoVd.js +0 -207
  291. package/storybook-static/assets/axe-Bq-2xuso.js +0 -20
  292. package/storybook-static/assets/browserAndReact-fXgh8QfO.js +0 -70
  293. package/storybook-static/assets/check-wNoLJyvD.js +0 -1
  294. package/storybook-static/assets/chevron-down-DjM4Yyml.js +0 -1
  295. package/storybook-static/assets/chevron-left-BT138_KT.js +0 -1
  296. package/storybook-static/assets/chevron-right-DEvxOiq2.js +0 -1
  297. package/storybook-static/assets/circle-check-BDVZ6tz8.js +0 -1
  298. package/storybook-static/assets/filesAndExcel-Bj4tkdkM.js +0 -92
  299. package/storybook-static/assets/floating-ui.react-BewtdZNK.js +0 -1
  300. package/storybook-static/assets/formatter-L2YTDE3Q-x0raBH34.js +0 -1
  301. package/storybook-static/assets/formatters-DYZ7voq3.js +0 -202
  302. package/storybook-static/assets/formatters-runtime-Ddmbt5yI.js +0 -329
  303. package/storybook-static/assets/iframe-C7ggO0sY.js +0 -1
  304. package/storybook-static/assets/odata-ClP2t_-O.js +0 -1
  305. package/storybook-static/assets/odataAndTables-Cjwl3uWE.js +0 -77
  306. package/storybook-static/assets/pureUtilities-CO1AJvbl.js +0 -30
  307. package/storybook-static/assets/react-18-CgkwBzTo.js +0 -9
  308. package/storybook-static/assets/react-D4nkG-T7.js +0 -9
  309. package/storybook-static/assets/runtimeAndState-TcnlLgJx.js +0 -93
  310. package/storybook-static/assets/syntaxhighlighter-T5IQBZDB-BIwIp4cU.js +0 -6
  311. package/storybook-static/assets/usePickerDefaultFilter-Be420WNF.js +0 -1
  312. package/storybook-static/assets/x-zmaXH4MN.js +0 -1
@@ -0,0 +1,860 @@
1
+ import{n as e}from"./rolldown-runtime-DkW27tQK.js";import{n as t}from"./iframe-CViB2sFm.js";import{i as n,r}from"./react-Bl2r1tuC.js";import{l as i,m as a}from"./blocks-B8F5vBhs.js";function o(e){let t={a:`a`,code:`code`,h1:`h1`,h2:`h2`,h3:`h3`,li:`li`,ol:`ol`,p:`p`,pre:`pre`,table:`table`,tbody:`tbody`,td:`td`,th:`th`,thead:`thead`,tr:`tr`,ul:`ul`,...n(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(i,{title:`Foundation Lib/API/Formulas`}),`
2
+ `,(0,c.jsx)(t.h1,{id:`табличные-формулы`,children:`Табличные формулы`}),`
3
+ `,(0,c.jsxs)(t.p,{children:[`Модуль `,(0,c.jsx)(t.code,{children:`@ryuzaki13/react-foundation-lib/formulas`}),` предоставляет безопасную инфраструктуру для заранее написанных клиентских формул таблицы.`]}),`
4
+ `,(0,c.jsx)(t.p,{children:`Формула получает значения других полей текущей строки, выполняет синхронный расчёт и возвращает конечное JavaScript-число. Например, она может вычислить сумму, разницу, отношение или процент для calculated-колонки.`}),`
5
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-text`,children:`данные строки + упорядоченные зависимости
6
+
7
+ зарегистрированная формула
8
+
9
+ конечное число или
10
+ контролируемая причина ошибки выполнения
11
+ `})}),`
12
+ `,(0,c.jsx)(t.p,{children:`README рассчитан на разработчика без доступа к исходному коду. Здесь описано точное поведение всего публичного API, включая преобразование значений, реестр, validation, ошибки и связь с formatter pipeline.`}),`
13
+ `,(0,c.jsx)(t.h2,{id:`содержание`,children:`Содержание`}),`
14
+ `,(0,c.jsxs)(t.ul,{children:[`
15
+ `,(0,c.jsx)(t.li,{children:(0,c.jsx)(t.a,{href:`#%D0%BD%D0%B0%D0%B7%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B5-%D0%B8-%D0%B3%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D1%8B`,children:`Назначение и границы`})}),`
16
+ `,(0,c.jsx)(t.li,{children:(0,c.jsx)(t.a,{href:`#%D1%83%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0-%D0%B8-%D0%B8%D0%BC%D0%BF%D0%BE%D1%80%D1%82`,children:`Установка и импорт`})}),`
17
+ `,(0,c.jsx)(t.li,{children:(0,c.jsx)(t.a,{href:`#%D0%B1%D1%8B%D1%81%D1%82%D1%80%D1%8B%D0%B9-%D1%81%D1%82%D0%B0%D1%80%D1%82`,children:`Быстрый старт`})}),`
18
+ `,(0,c.jsx)(t.li,{children:(0,c.jsx)(t.a,{href:`#%D0%BE%D1%81%D0%BD%D0%BE%D0%B2%D0%BD%D1%8B%D0%B5-%D0%BF%D0%BE%D0%BD%D1%8F%D1%82%D0%B8%D1%8F`,children:`Основные понятия`})}),`
19
+ `,(0,c.jsx)(t.li,{children:(0,c.jsx)(t.a,{href:`#%D0%BE%D0%BF%D0%B8%D1%81%D0%B0%D0%BD%D0%B8%D0%B5-%D1%84%D0%BE%D1%80%D0%BC%D1%83%D0%BB%D1%8B`,children:`Описание формулы`})}),`
20
+ `,(0,c.jsx)(t.li,{children:(0,c.jsx)(t.a,{href:`#%D0%BA%D0%BE%D0%BD%D1%82%D0%B5%D0%BA%D1%81%D1%82-%D1%84%D0%BE%D1%80%D0%BC%D1%83%D0%BB%D1%8B`,children:`Контекст формулы`})}),`
21
+ `,(0,c.jsx)(t.li,{children:(0,c.jsxs)(t.a,{href:`#%D1%87%D0%B8%D1%81%D0%BB%D0%BE%D0%B2%D0%BE%D0%B5-%D0%BF%D1%80%D0%B5%D0%BE%D0%B1%D1%80%D0%B0%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5-ctxnum`,children:[`Числовое преобразование `,(0,c.jsx)(t.code,{children:`ctx.num`})]})}),`
22
+ `,(0,c.jsx)(t.li,{children:(0,c.jsx)(t.a,{href:`#%D1%81%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5-%D0%B8-%D1%83%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0-%D1%80%D0%B5%D0%B5%D1%81%D1%82%D1%80%D0%B0`,children:`Создание и установка реестра`})}),`
23
+ `,(0,c.jsx)(t.li,{children:(0,c.jsx)(t.a,{href:`#%D1%87%D1%82%D0%B5%D0%BD%D0%B8%D0%B5-%D0%B0%D0%BA%D1%82%D0%B8%D0%B2%D0%BD%D0%BE%D0%B3%D0%BE-%D1%80%D0%B5%D0%B5%D1%81%D1%82%D1%80%D0%B0`,children:`Чтение активного реестра`})}),`
24
+ `,(0,c.jsx)(t.li,{children:(0,c.jsx)(t.a,{href:`#%D0%B2%D1%8B%D0%BF%D0%BE%D0%BB%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5-%D1%84%D0%BE%D1%80%D0%BC%D1%83%D0%BB%D1%8B`,children:`Выполнение формулы`})}),`
25
+ `,(0,c.jsx)(t.li,{children:(0,c.jsx)(t.a,{href:`#%D0%BF%D1%80%D0%B5%D0%B4%D0%B2%D0%B0%D1%80%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%B0%D1%8F-%D0%BA%D0%BE%D0%BC%D0%BF%D0%B8%D0%BB%D1%8F%D1%86%D0%B8%D1%8F`,children:`Предварительная компиляция`})}),`
26
+ `,(0,c.jsx)(t.li,{children:(0,c.jsx)(t.a,{href:`#%D0%B2%D0%B0%D0%BB%D0%B8%D0%B4%D0%B0%D1%86%D0%B8%D1%8F-%D0%B7%D0%B0%D0%B2%D0%B8%D1%81%D0%B8%D0%BC%D0%BE%D1%81%D1%82%D0%B5%D0%B9`,children:`Валидация зависимостей`})}),`
27
+ `,(0,c.jsx)(t.li,{children:(0,c.jsx)(t.a,{href:`#%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D1%86%D0%B8%D1%8F-%D1%81-formatter-pipeline`,children:`Интеграция с formatter pipeline`})}),`
28
+ `,(0,c.jsx)(t.li,{children:(0,c.jsx)(t.a,{href:`#%D0%BE%D1%82%D0%BB%D0%B8%D1%87%D0%B8%D0%B5-%D0%BE%D1%82-row-based-formatter`,children:`Отличие от row-based formatter`})}),`
29
+ `,(0,c.jsx)(t.li,{children:(0,c.jsx)(t.a,{href:`#%D0%B0%D1%80%D1%85%D0%B8%D1%82%D0%B5%D0%BA%D1%82%D1%83%D1%80%D0%B0-%D0%B8-%D0%B1%D0%B5%D0%B7%D0%BE%D0%BF%D0%B0%D1%81%D0%BD%D0%BE%D1%81%D1%82%D1%8C`,children:`Архитектура и безопасность`})}),`
30
+ `,(0,c.jsx)(t.li,{children:(0,c.jsx)(t.a,{href:`#%D1%82%D0%B5%D1%81%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5`,children:`Тестирование`})}),`
31
+ `,(0,c.jsx)(t.li,{children:(0,c.jsx)(t.a,{href:`#%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%B4%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D1%8C`,children:`Производительность`})}),`
32
+ `,(0,c.jsx)(t.li,{children:(0,c.jsx)(t.a,{href:`#%D1%87%D0%B0%D1%81%D1%82%D1%8B%D0%B5-%D0%BE%D1%88%D0%B8%D0%B1%D0%BA%D0%B8`,children:`Частые ошибки`})}),`
33
+ `,(0,c.jsx)(t.li,{children:(0,c.jsx)(t.a,{href:`#api-%D1%81%D0%BF%D1%80%D0%B0%D0%B2%D0%BA%D0%B0`,children:`API-справка`})}),`
34
+ `]}),`
35
+ `,(0,c.jsx)(t.h2,{id:`назначение-и-границы`,children:`Назначение и границы`}),`
36
+ `,(0,c.jsx)(t.h3,{id:`что-делает-модуль`,children:`Что делает модуль`}),`
37
+ `,(0,c.jsxs)(t.ul,{children:[`
38
+ `,(0,c.jsx)(t.li,{children:`описывает типизированный контракт числовой формулы;`}),`
39
+ `,(0,c.jsx)(t.li,{children:`связывает dependency indexes с полями текущей строки;`}),`
40
+ `,(0,c.jsx)(t.li,{children:`создаёт нормализованный реестр формул host-приложения;`}),`
41
+ `,(0,c.jsx)(t.li,{children:`хранит один активный реестр в текущем экземпляре модуля;`}),`
42
+ `,(0,c.jsx)(t.li,{children:`выполняет формулы без выбрасывания их runtime-ошибок наружу;`}),`
43
+ `,(0,c.jsx)(t.li,{children:`компилирует formula + keys в переиспользуемый executor;`}),`
44
+ `,(0,c.jsx)(t.li,{children:`проверяет существование формулы и корректность выбранных dependencies;`}),`
45
+ `,(0,c.jsx)(t.li,{children:`сообщает, какие dependency indexes реально использовала формула на тестовых данных.`}),`
46
+ `]}),`
47
+ `,(0,c.jsx)(t.h3,{id:`чего-модуль-не-делает`,children:`Чего модуль не делает`}),`
48
+ `,(0,c.jsxs)(t.ul,{children:[`
49
+ `,(0,c.jsx)(t.li,{children:`не содержит встроенного каталога бизнес-формул;`}),`
50
+ `,(0,c.jsx)(t.li,{children:`не разбирает текст математического выражения;`}),`
51
+ `,(0,c.jsxs)(t.li,{children:[`не использует `,(0,c.jsx)(t.code,{children:`eval`}),` или `,(0,c.jsx)(t.code,{children:`new Function`}),`;`]}),`
52
+ `,(0,c.jsx)(t.li,{children:`не выполняет произвольный пользовательский JavaScript;`}),`
53
+ `,(0,c.jsx)(t.li,{children:`не загружает зависимости с сервера;`}),`
54
+ `,(0,c.jsx)(t.li,{children:`не добавляет нужные поля в OData/HTTP-запрос;`}),`
55
+ `,(0,c.jsx)(t.li,{children:`не форматирует результат для UI;`}),`
56
+ `,(0,c.jsx)(t.li,{children:`не выбирает fallback для конкретной таблицы;`}),`
57
+ `,(0,c.jsx)(t.li,{children:`не поддерживает асинхронные формулы;`}),`
58
+ `,(0,c.jsx)(t.li,{children:`не хранит function body в JSON или БД.`}),`
59
+ `]}),`
60
+ `,(0,c.jsxs)(t.p,{children:[`Host-приложение владеет прикладными `,(0,c.jsx)(t.code,{children:`TableFormulaDefinition`}),`: оно объявляет их в коде, тестирует, собирает в реестр и устанавливает на старте приложения.`]}),`
61
+ `,(0,c.jsxs)(t.p,{children:[`Сериализуемая конфигурация колонки хранит только стабильный `,(0,c.jsx)(t.code,{children:`formulaId`}),` и ordered dependencies. Реальная функция остаётся доверенным кодом приложения.`]}),`
62
+ `,(0,c.jsx)(t.h2,{id:`установка-и-импорт`,children:`Установка и импорт`}),`
63
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-bash`,children:`npm install @ryuzaki13/react-foundation-lib
64
+ `})}),`
65
+ `,(0,c.jsxs)(t.p,{children:[`Используйте только опубликованный package subpath `,(0,c.jsx)(t.code,{children:`/formulas`}),`:`]}),`
66
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`import {
67
+ compileTableFormula,
68
+ configureTableFormulaRegistry,
69
+ createTableFormulaRegistry,
70
+ executeTableFormula,
71
+ getTableFormulaById,
72
+ getTableFormulaList,
73
+ validateTableFormulaDependencies
74
+ } from "@ryuzaki13/react-foundation-lib/formulas";
75
+
76
+ import type { TableFormulaDefinition, TableFormulaExecutionResult, TableFormulaRegistry } from "@ryuzaki13/react-foundation-lib/formulas";
77
+ `})}),`
78
+ `,(0,c.jsx)(t.p,{children:`Корневой импорт пакета и private imports из исходников не поддерживаются:`}),`
79
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`// Неправильно.
80
+ // import { executeTableFormula } from "@ryuzaki13/react-foundation-lib";
81
+ // import { executeTableFormula } from "@ryuzaki13/react-foundation-lib/src/formulas/execute";
82
+
83
+ // Правильно.
84
+ import { executeTableFormula } from "@ryuzaki13/react-foundation-lib/formulas";
85
+ `})}),`
86
+ `,(0,c.jsx)(t.p,{children:`Публичный модуль не зависит от React, DOM или browser-only API. Его runtime можно использовать в browser, worker и Node.js.`}),`
87
+ `,(0,c.jsx)(t.h2,{id:`быстрый-старт`,children:`Быстрый старт`}),`
88
+ `,(0,c.jsx)(t.h3,{id:`1-объявите-формулу`,children:`1. Объявите формулу`}),`
89
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`import type { TableFormulaDefinition } from "@ryuzaki13/react-foundation-lib/formulas";
90
+
91
+ const sumFormula: TableFormulaDefinition = {
92
+ id: "sum",
93
+ name: "Сумма",
94
+ description: "Складывает две выбранные зависимости: $0 + $1.",
95
+ args: ["первое слагаемое", "второе слагаемое"],
96
+ keywords: ["сложение", "арифметика"],
97
+ fn: (ctx) => ctx.num(0) + ctx.num(1)
98
+ };
99
+ `})}),`
100
+ `,(0,c.jsx)(t.h3,{id:`2-создайте-и-установите-реестр`,children:`2. Создайте и установите реестр`}),`
101
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`import { configureTableFormulaRegistry, createTableFormulaRegistry } from "@ryuzaki13/react-foundation-lib/formulas";
102
+
103
+ const registry = createTableFormulaRegistry([sumFormula]);
104
+
105
+ configureTableFormulaRegistry(registry);
106
+ `})}),`
107
+ `,(0,c.jsx)(t.p,{children:`Это bootstrap-операция. Выполните её один раз до первого чтения, validation, compile или execute.`}),`
108
+ `,(0,c.jsx)(t.h3,{id:`3-выполните-формулу`,children:`3. Выполните формулу`}),`
109
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`const result = executeTableFormula({
110
+ formulaId: "sum",
111
+ keys: ["planned", "actual"],
112
+ rowData: {
113
+ planned: 100,
114
+ actual: "25"
115
+ }
116
+ });
117
+
118
+ if (result.ok) {
119
+ console.log(result.value); // 125
120
+ } else {
121
+ console.error(result.reason);
122
+ }
123
+ `})}),`
124
+ `,(0,c.jsxs)(t.p,{children:[`Порядок `,(0,c.jsx)(t.code,{children:`keys`}),` определяет смысл indexes:`]}),`
125
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-text`,children:`ctx.num(0) → rowData.planned
126
+ ctx.num(1) → rowData.actual
127
+ `})}),`
128
+ `,(0,c.jsx)(t.p,{children:`Формула не знает имена выбранных полей заранее. Она знает только позиции аргументов.`}),`
129
+ `,(0,c.jsx)(t.h2,{id:`основные-понятия`,children:`Основные понятия`}),`
130
+ `,(0,c.jsx)(t.h3,{id:`строка-данных`,children:`Строка данных`}),`
131
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`type TableFormulaRowData = Record<string, unknown>;
132
+ `})}),`
133
+ `,(0,c.jsxs)(t.p,{children:[`Это обычный JavaScript-объект, где ключ — id поля, а значение пока считается `,(0,c.jsx)(t.code,{children:`unknown`}),`:`]}),`
134
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`const rowData = {
135
+ planned: 100,
136
+ actual: "25",
137
+ label: "План"
138
+ };
139
+ `})}),`
140
+ `,(0,c.jsx)(t.p,{children:`Модуль не копирует и не валидирует всю строку. Он читает только keys, к которым обращается formula context.`}),`
141
+ `,(0,c.jsx)(t.h3,{id:`зависимости-и-keys`,children:`Зависимости и keys`}),`
142
+ `,(0,c.jsx)(t.p,{children:`Dependencies — упорядоченный массив id полей:`}),`
143
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`const keys = ["planned", "actual"];
144
+ `})}),`
145
+ `,(0,c.jsx)(t.p,{children:`Позиция является частью контракта:`}),`
146
+ `,(0,c.jsxs)(t.ul,{children:[`
147
+ `,(0,c.jsxs)(t.li,{children:[(0,c.jsx)(t.code,{children:`0`}),` означает `,(0,c.jsx)(t.code,{children:`planned`}),`;`]}),`
148
+ `,(0,c.jsxs)(t.li,{children:[(0,c.jsx)(t.code,{children:`1`}),` означает `,(0,c.jsx)(t.code,{children:`actual`}),`.`]}),`
149
+ `]}),`
150
+ `,(0,c.jsx)(t.p,{children:`Если поменять элементы местами, формула получит другой смысл без TypeScript-ошибки:`}),`
151
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`// Формула вычисляет $0 - $1.
152
+ keys: ["planned", "actual"]; // planned - actual
153
+ keys: ["actual", "planned"]; // actual - planned
154
+ `})}),`
155
+ `,(0,c.jsxs)(t.p,{children:[`Названия `,(0,c.jsx)(t.code,{children:`keys`}),` и `,(0,c.jsx)(t.code,{children:`dependencies`}),` обозначают один и тот же ordered mapping в разных API:`]}),`
156
+ `,(0,c.jsxs)(t.ul,{children:[`
157
+ `,(0,c.jsxs)(t.li,{children:[(0,c.jsx)(t.code,{children:`compileTableFormula`}),` и `,(0,c.jsx)(t.code,{children:`executeTableFormula`}),` принимают `,(0,c.jsx)(t.code,{children:`keys`}),`;`]}),`
158
+ `,(0,c.jsxs)(t.li,{children:[(0,c.jsx)(t.code,{children:`validateTableFormulaDependencies`}),` принимает `,(0,c.jsx)(t.code,{children:`dependencies`}),`;`]}),`
159
+ `,(0,c.jsxs)(t.li,{children:[`formatter runtime field обычно хранит `,(0,c.jsx)(t.code,{children:`formulaDependencies`}),`.`]}),`
160
+ `]}),`
161
+ `,(0,c.jsx)(t.h3,{id:`реестр`,children:`Реестр`}),`
162
+ `,(0,c.jsxs)(t.p,{children:[`Registry связывает стабильный `,(0,c.jsx)(t.code,{children:`formulaId`}),` с definition-функцией:`]}),`
163
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-text`,children:`"sum" → sumFormula
164
+ "ratio" → ratioFormula
165
+ `})}),`
166
+ `,(0,c.jsx)(t.p,{children:`Поскольку function не сериализуется, сохранённая конфигурация должна содержать id, а приложение при запуске обязано установить реестр с соответствующим definition.`}),`
167
+ `,(0,c.jsx)(t.h2,{id:`описание-формулы`,children:`Описание формулы`}),`
168
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`interface TableFormulaDefinition {
169
+ id: string;
170
+ name: string;
171
+ description: string;
172
+ args?: readonly string[];
173
+ keywords?: readonly string[];
174
+ fn: TableFormulaFn;
175
+ }
176
+ `})}),`
177
+ `,(0,c.jsx)(t.h3,{id:`id`,children:(0,c.jsx)(t.code,{children:`id`})}),`
178
+ `,(0,c.jsx)(t.p,{children:`Устойчивый технический идентификатор:`}),`
179
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`id: "share-of-total-percent";
180
+ `})}),`
181
+ `,(0,c.jsx)(t.p,{children:`Он:`}),`
182
+ `,(0,c.jsxs)(t.ul,{children:[`
183
+ `,(0,c.jsx)(t.li,{children:`trim-ится при создании реестра;`}),`
184
+ `,(0,c.jsx)(t.li,{children:`обязан быть непустым;`}),`
185
+ `,(0,c.jsx)(t.li,{children:`обязан быть уникальным после trim;`}),`
186
+ `,(0,c.jsx)(t.li,{children:`может сохраняться в пользовательских конфигурациях;`}),`
187
+ `,(0,c.jsx)(t.li,{children:`должен оставаться стабильным после релиза.`}),`
188
+ `]}),`
189
+ `,(0,c.jsx)(t.p,{children:`Не используйте display name как id и не генерируйте случайный id при каждом запуске.`}),`
190
+ `,(0,c.jsx)(t.h3,{id:`name`,children:(0,c.jsx)(t.code,{children:`name`})}),`
191
+ `,(0,c.jsx)(t.p,{children:`Короткое название для каталога или select:`}),`
192
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`name: "Процентная доля";
193
+ `})}),`
194
+ `,(0,c.jsx)(t.p,{children:`Factory удаляет внешние пробелы, но не запрещает пустое name. За качество пользовательского каталога отвечает host.`}),`
195
+ `,(0,c.jsx)(t.h3,{id:`description`,children:(0,c.jsx)(t.code,{children:`description`})}),`
196
+ `,(0,c.jsx)(t.p,{children:`Объясняет формулу и порядок зависимостей:`}),`
197
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`description: "100 * $0 / ($0 + $1)";
198
+ `})}),`
199
+ `,(0,c.jsxs)(t.p,{children:[`Factory trim-ит строку, но не анализирует выражение. `,(0,c.jsx)(t.code,{children:`$0`}),`, `,(0,c.jsx)(t.code,{children:`$1`}),` — только принятая человеком нотация документации, а не parser syntax.`]}),`
200
+ `,(0,c.jsx)(t.h3,{id:`args`,children:(0,c.jsx)(t.code,{children:`args`})}),`
201
+ `,(0,c.jsx)(t.p,{children:`Необязательные подписи positional arguments:`}),`
202
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`args: ["выбранный показатель", "остальная часть"];
203
+ `})}),`
204
+ `,(0,c.jsx)(t.p,{children:`Runtime не проверяет их количество и не связывает их с keys автоматически. Поле предназначено для редактора и документации.`}),`
205
+ `,(0,c.jsxs)(t.p,{children:[`Текущая factory сохраняет исходную ссылку на массив `,(0,c.jsx)(t.code,{children:`args`}),`; она не клонирует и не замораживает сам массив. Передавайте стабильный readonly-массив и не мутируйте его после создания registry.`]}),`
206
+ `,(0,c.jsx)(t.h3,{id:`keywords`,children:(0,c.jsx)(t.code,{children:`keywords`})}),`
207
+ `,(0,c.jsx)(t.p,{children:`Необязательные поисковые слова каталога:`}),`
208
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`keywords: ["процент", "доля"];
209
+ `})}),`
210
+ `,(0,c.jsx)(t.p,{children:`Factory создаёт отдельную копию массива, но элементы не trim-ит, а сам вложенный массив глубоко не замораживает. Считайте metadata read-only.`}),`
211
+ `,(0,c.jsx)(t.h3,{id:`fn`,children:(0,c.jsx)(t.code,{children:`fn`})}),`
212
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`type TableFormulaFn = (ctx: TableFormulaContext) => number;
213
+ `})}),`
214
+ `,(0,c.jsx)(t.p,{children:`Функция обязана:`}),`
215
+ `,(0,c.jsxs)(t.ul,{children:[`
216
+ `,(0,c.jsx)(t.li,{children:`работать синхронно;`}),`
217
+ `,(0,c.jsxs)(t.li,{children:[`возвращать `,(0,c.jsx)(t.code,{children:`number`}),`;`]}),`
218
+ `,(0,c.jsx)(t.li,{children:`возвращать только конечный результат;`}),`
219
+ `,(0,c.jsx)(t.li,{children:`быть детерминированной для одинакового контекста;`}),`
220
+ `,(0,c.jsx)(t.li,{children:`не иметь побочных эффектов;`}),`
221
+ `,(0,c.jsx)(t.li,{children:`самостоятельно обрабатывать деление на ноль и другие бизнес-границы.`}),`
222
+ `]}),`
223
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`const ratioFormula: TableFormulaDefinition = {
224
+ id: "ratio",
225
+ name: "Отношение",
226
+ description: "$0 / $1",
227
+ args: ["делимое", "делитель"],
228
+ fn: (ctx) => {
229
+ const divisor = ctx.num(1);
230
+ return divisor === 0 ? 0 : ctx.num(0) / divisor;
231
+ }
232
+ };
233
+ `})}),`
234
+ `,(0,c.jsx)(t.h2,{id:`контекст-формулы`,children:`Контекст формулы`}),`
235
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`interface TableFormulaContext {
236
+ key: (index: number) => string | undefined;
237
+ value: (index: number) => unknown;
238
+ num: (index: number) => number;
239
+ }
240
+ `})}),`
241
+ `,(0,c.jsx)(t.h3,{id:`ctxkeyindex`,children:(0,c.jsx)(t.code,{children:`ctx.key(index)`})}),`
242
+ `,(0,c.jsx)(t.p,{children:`Возвращает id dependency по индексу:`}),`
243
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`// keys = ["planned", "actual"]
244
+ ctx.key(0); // "planned"
245
+ ctx.key(1); // "actual"
246
+ ctx.key(2); // undefined
247
+ ctx.key(-1); // undefined
248
+ ctx.key(1.5); // undefined
249
+ `})}),`
250
+ `,(0,c.jsx)(t.p,{children:`Допустим только целый неотрицательный index в пределах массива.`}),`
251
+ `,(0,c.jsxs)(t.p,{children:[`Пустая строка технически может вернуться из `,(0,c.jsx)(t.code,{children:`key`}),`, если она была передана в `,(0,c.jsx)(t.code,{children:`keys`}),`, но `,(0,c.jsx)(t.code,{children:`value`}),` и `,(0,c.jsx)(t.code,{children:`num`}),` считают пустой key отсутствующим. Используйте только непустые dependency ids.`]}),`
252
+ `,(0,c.jsx)(t.h3,{id:`ctxvalueindex`,children:(0,c.jsx)(t.code,{children:`ctx.value(index)`})}),`
253
+ `,(0,c.jsx)(t.p,{children:`Возвращает исходное значение без преобразования:`}),`
254
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`// rowData.actual === "25"
255
+ ctx.value(1); // "25"
256
+ `})}),`
257
+ `,(0,c.jsxs)(t.p,{children:[`Для неправильного индекса, пустого key или отсутствующего свойства возвращается `,(0,c.jsx)(t.code,{children:`undefined`}),`.`]}),`
258
+ `,(0,c.jsxs)(t.p,{children:[`Используйте `,(0,c.jsx)(t.code,{children:`value`}),`, когда нужно отличать отсутствующее значение от нуля или применять собственный parser:`]}),`
259
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`fn: (ctx) => {
260
+ const raw = ctx.value(0);
261
+ if (raw === null || raw === undefined || raw === "") return 0;
262
+
263
+ const value = Number(raw);
264
+ return Number.isFinite(value) ? value : 0;
265
+ };
266
+ `})}),`
267
+ `,(0,c.jsx)(t.h3,{id:`ctxnumindex`,children:(0,c.jsx)(t.code,{children:`ctx.num(index)`})}),`
268
+ `,(0,c.jsxs)(t.p,{children:[`Читает значение и применяет обычный `,(0,c.jsx)(t.code,{children:`Number(value)`}),`. Если результат не конечный, возвращает `,(0,c.jsx)(t.code,{children:`0`}),`.`]}),`
269
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`ctx.num(0) + ctx.num(1);
270
+ `})}),`
271
+ `,(0,c.jsx)(t.p,{children:`Точная coercion-семантика описана в следующем разделе.`}),`
272
+ `,(0,c.jsx)(t.h3,{id:`createtableformulacontextargs`,children:(0,c.jsx)(t.code,{children:`createTableFormulaContext(args)`})}),`
273
+ `,(0,c.jsx)(t.p,{children:`Создаёт context вручную. Основные сценарии — unit-тест своей formula и validation infrastructure:`}),`
274
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`import { createTableFormulaContext } from "@ryuzaki13/react-foundation-lib/formulas";
275
+
276
+ const context = createTableFormulaContext({
277
+ rowData: {
278
+ price: "12.5",
279
+ count: 4
280
+ },
281
+ keys: ["price", "count"]
282
+ });
283
+
284
+ context.value(0); // "12.5"
285
+ context.num(0); // 12.5
286
+ context.num(1); // 4
287
+ `})}),`
288
+ `,(0,c.jsxs)(t.p,{children:[(0,c.jsx)(t.code,{children:`keys`}),` копируется при создании context. Изменение исходного массива после вызова не меняет mapping. `,(0,c.jsx)(t.code,{children:`rowData`}),` не копируется: context читает переданный объект.`]}),`
289
+ `,(0,c.jsx)(t.h3,{id:`instrumentation`,children:`Instrumentation`}),`
290
+ `,(0,c.jsxs)(t.p,{children:[(0,c.jsx)(t.code,{children:`createTableFormulaContext`}),` принимает необязательные callbacks для наблюдения за indexes:`]}),`
291
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`const usedIndexes: number[] = [];
292
+ const invalidIndexes: number[] = [];
293
+
294
+ const context = createTableFormulaContext({
295
+ rowData: { A: 10 },
296
+ keys: ["A"],
297
+ instrumentation: {
298
+ onReadIndex: (index) => usedIndexes.push(index),
299
+ onOutOfRangeIndex: (index) => invalidIndexes.push(index)
300
+ }
301
+ });
302
+
303
+ context.num(0); // usedIndexes получает 0
304
+ context.num(2); // usedIndexes и invalidIndexes получают 2
305
+ context.num(-1); // invalidIndexes получает -1
306
+ `})}),`
307
+ `,(0,c.jsxs)(t.p,{children:[`Для отрицательного, дробного или другого неправильного index вызывается только `,(0,c.jsx)(t.code,{children:`onOutOfRangeIndex`}),`. Для целого неотрицательного index сначала вызывается `,(0,c.jsx)(t.code,{children:`onReadIndex`}),`, даже если index оказался больше последнего элемента, а затем — `,(0,c.jsx)(t.code,{children:`onOutOfRangeIndex`}),`.`]}),`
308
+ `,(0,c.jsx)(t.p,{children:`Тип instrumentation отдельно не экспортируется по имени, но TypeScript проверяет объект непосредственно в аргументах функции.`}),`
309
+ `,(0,c.jsxs)(t.h2,{id:`числовое-преобразование-ctxnum`,children:[`Числовое преобразование `,(0,c.jsx)(t.code,{children:`ctx.num`})]}),`
310
+ `,(0,c.jsxs)(t.p,{children:[(0,c.jsx)(t.code,{children:`ctx.num`}),` не использует `,(0,c.jsx)(t.code,{children:`toFiniteNumber`}),` из formatter-ов. Внутри выполняется:`]}),`
311
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`const normalized = Number(value);
312
+ return Number.isFinite(normalized) ? normalized : 0;
313
+ `})}),`
314
+ `,(0,c.jsx)(t.p,{children:`Отсюда следует стандартная JavaScript-coercion:`}),`
315
+ `,(0,c.jsxs)(t.table,{children:[(0,c.jsx)(t.thead,{children:(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.th,{children:`Исходное значение`}),(0,c.jsx)(t.th,{style:{textAlign:`right`},children:(0,c.jsx)(t.code,{children:`ctx.num(index)`})}),(0,c.jsx)(t.th,{children:`Причина`})]})}),(0,c.jsxs)(t.tbody,{children:[(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`10`})}),(0,c.jsx)(t.td,{style:{textAlign:`right`},children:(0,c.jsx)(t.code,{children:`10`})}),(0,c.jsx)(t.td,{children:`уже конечный number`})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`"10"`})}),(0,c.jsx)(t.td,{style:{textAlign:`right`},children:(0,c.jsx)(t.code,{children:`10`})}),(0,c.jsx)(t.td,{children:`numeric string`})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`"12.5"`})}),(0,c.jsx)(t.td,{style:{textAlign:`right`},children:(0,c.jsx)(t.code,{children:`12.5`})}),(0,c.jsxs)(t.td,{children:[`точка поддерживается `,(0,c.jsx)(t.code,{children:`Number`})]})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`""`})}),(0,c.jsx)(t.td,{style:{textAlign:`right`},children:(0,c.jsx)(t.code,{children:`0`})}),(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`Number("") === 0`})})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`" "`})}),(0,c.jsx)(t.td,{style:{textAlign:`right`},children:(0,c.jsx)(t.code,{children:`0`})}),(0,c.jsx)(t.td,{children:`whitespace string становится нулём`})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`null`})}),(0,c.jsx)(t.td,{style:{textAlign:`right`},children:(0,c.jsx)(t.code,{children:`0`})}),(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`Number(null) === 0`})})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`undefined`})}),(0,c.jsx)(t.td,{style:{textAlign:`right`},children:(0,c.jsx)(t.code,{children:`0`})}),(0,c.jsxs)(t.td,{children:[(0,c.jsx)(t.code,{children:`Number(undefined)`}),` даёт `,(0,c.jsx)(t.code,{children:`NaN`}),`, затем fallback`]})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`true`})}),(0,c.jsx)(t.td,{style:{textAlign:`right`},children:(0,c.jsx)(t.code,{children:`1`})}),(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`Number(true) === 1`})})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`false`})}),(0,c.jsx)(t.td,{style:{textAlign:`right`},children:(0,c.jsx)(t.code,{children:`0`})}),(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`Number(false) === 0`})})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`"abc"`})}),(0,c.jsx)(t.td,{style:{textAlign:`right`},children:(0,c.jsx)(t.code,{children:`0`})}),(0,c.jsxs)(t.td,{children:[(0,c.jsx)(t.code,{children:`NaN`}),`, затем fallback`]})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`Infinity`})}),(0,c.jsx)(t.td,{style:{textAlign:`right`},children:(0,c.jsx)(t.code,{children:`0`})}),(0,c.jsx)(t.td,{children:`не finite`})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`"1 234,5"`})}),(0,c.jsx)(t.td,{style:{textAlign:`right`},children:(0,c.jsx)(t.code,{children:`0`})}),(0,c.jsxs)(t.td,{children:[`локализованная строка не поддержана `,(0,c.jsx)(t.code,{children:`Number`})]})]})]})]}),`
316
+ `,(0,c.jsx)(t.p,{children:`Это удобно для простых числовых DTO, но не является строгой validation.`}),`
317
+ `,(0,c.jsx)(t.p,{children:`Если строка может содержать пробелы группировки или запятую, выберите явную policy:`}),`
318
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`import { toFiniteNumber } from "@ryuzaki13/react-foundation-lib/formatters";
319
+ import type { TableFormulaDefinition } from "@ryuzaki13/react-foundation-lib/formulas";
320
+
321
+ const localizedNumberFormula: TableFormulaDefinition = {
322
+ id: "localized-value",
323
+ name: "Локализованное число",
324
+ description: "Читает первую зависимость через SAP-like parser.",
325
+ fn: (ctx) => toFiniteNumber(ctx.value(0)) ?? 0
326
+ };
327
+ `})}),`
328
+ `,(0,c.jsx)(t.p,{children:`Не добавляйте parser автоматически во все formulas, если transport уже возвращает numbers. Выбор зависит от контракта данных host-приложения.`}),`
329
+ `,(0,c.jsx)(t.h2,{id:`создание-и-установка-реестра`,children:`Создание и установка реестра`}),`
330
+ `,(0,c.jsx)(t.h3,{id:`createtableformularegistrydefinitions`,children:(0,c.jsx)(t.code,{children:`createTableFormulaRegistry(definitions)`})}),`
331
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`function createTableFormulaRegistry(definitions: readonly TableFormulaDefinition[]): TableFormulaRegistry;
332
+ `})}),`
333
+ `,(0,c.jsx)(t.p,{children:`Factory проходит definitions в исходном порядке и для каждого элемента:`}),`
334
+ `,(0,c.jsxs)(t.ol,{children:[`
335
+ `,(0,c.jsxs)(t.li,{children:[`trim-ит `,(0,c.jsx)(t.code,{children:`id`}),`;`]}),`
336
+ `,(0,c.jsx)(t.li,{children:`запрещает пустой id;`}),`
337
+ `,(0,c.jsx)(t.li,{children:`запрещает повторный id после trim;`}),`
338
+ `,(0,c.jsxs)(t.li,{children:[`trim-ит `,(0,c.jsx)(t.code,{children:`name`}),` и `,(0,c.jsx)(t.code,{children:`description`}),`;`]}),`
339
+ `,(0,c.jsxs)(t.li,{children:[`копирует `,(0,c.jsx)(t.code,{children:`keywords`}),`, если они заданы;`]}),`
340
+ `,(0,c.jsx)(t.li,{children:`создаёт новый поверхностно замороженный definition;`}),`
341
+ `,(0,c.jsxs)(t.li,{children:[`добавляет его в ordered `,(0,c.jsx)(t.code,{children:`list`}),` и lookup `,(0,c.jsx)(t.code,{children:`byId`}),`.`]}),`
342
+ `]}),`
343
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`const registry = createTableFormulaRegistry([
344
+ {
345
+ id: " sum ",
346
+ name: " Сумма ",
347
+ description: " $0 + $1 ",
348
+ fn: (ctx) => ctx.num(0) + ctx.num(1)
349
+ }
350
+ ]);
351
+
352
+ registry.list[0].id; // "sum"
353
+ registry.list[0].name; // "Сумма"
354
+ registry.byId.get("sum") === registry.list[0]; // true
355
+ `})}),`
356
+ `,(0,c.jsx)(t.p,{children:`Пустой или дублирующийся id приводит к fail-fast исключению:`}),`
357
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`createTableFormulaRegistry([{ id: " ", name: "Пустая", description: "", fn: () => 0 }]);
358
+ // Error: Formula id не может быть пустым
359
+ `})}),`
360
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`createTableFormulaRegistry([
361
+ { id: "sum", name: "A", description: "", fn: () => 0 },
362
+ { id: " sum ", name: "B", description: "", fn: () => 0 }
363
+ ]);
364
+ // Error: дублирующийся formulaId
365
+ `})}),`
366
+ `,(0,c.jsx)(t.h3,{id:`readonly-и-freeze`,children:`Readonly и freeze`}),`
367
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`type TableFormulaRegistry = Readonly<{
368
+ list: readonly TableFormulaDefinition[];
369
+ byId: ReadonlyMap<string, TableFormulaDefinition>;
370
+ }>;
371
+ `})}),`
372
+ `,(0,c.jsx)(t.p,{children:`Registry object, list и каждый definition поверхностно заморожены. Это защищает основные metadata fields от обычной мутации.`}),`
373
+ `,(0,c.jsx)(t.p,{children:`Freeze не является глубоким:`}),`
374
+ `,(0,c.jsxs)(t.ul,{children:[`
375
+ `,(0,c.jsxs)(t.li,{children:[(0,c.jsx)(t.code,{children:`args`}),` сохраняет входную ссылку;`]}),`
376
+ `,(0,c.jsxs)(t.li,{children:[(0,c.jsx)(t.code,{children:`keywords`}),` копируется, но сам массив не заморожен;`]}),`
377
+ `,(0,c.jsxs)(t.li,{children:[(0,c.jsx)(t.code,{children:`byId`}),` типизирован как `,(0,c.jsx)(t.code,{children:`ReadonlyMap`}),`, однако runtime object остаётся обычным `,(0,c.jsx)(t.code,{children:`Map`}),`.`]}),`
378
+ `]}),`
379
+ `,(0,c.jsx)(t.p,{children:`Не обходите readonly casts и не мутируйте внутренности. Считайте registry полностью неизменяемым consumer-контрактом.`}),`
380
+ `,(0,c.jsx)(t.h3,{id:`configuretableformularegistryregistry`,children:(0,c.jsx)(t.code,{children:`configureTableFormulaRegistry(registry)`})}),`
381
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`configureTableFormulaRegistry(registry);
382
+ `})}),`
383
+ `,(0,c.jsx)(t.p,{children:`Заменяет активный module-level registry. По умолчанию активен пустой реестр, поэтому без настройки любой formula id считается неизвестным.`}),`
384
+ `,(0,c.jsx)(t.p,{children:`Правильный lifecycle:`}),`
385
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-text`,children:`объявить definitions
386
+
387
+ createTableFormulaRegistry
388
+
389
+ configureTableFormulaRegistry
390
+
391
+ validate configs
392
+
393
+ compile runtime fields
394
+
395
+ execute для строк
396
+ `})}),`
397
+ `,(0,c.jsx)(t.p,{children:`Устанавливайте registry в composition root до первого React render или другого consumer runtime.`}),`
398
+ `,(0,c.jsx)(t.h3,{id:`глобальность-реестра`,children:`Глобальность реестра`}),`
399
+ `,(0,c.jsxs)(t.p,{children:[`Активный registry один для загруженного экземпляра ESM-модуля. `,(0,c.jsx)(t.code,{children:`configureTableFormulaRegistry`}),` не объединяет catalogs, а полностью заменяет текущий.`]}),`
400
+ `,(0,c.jsx)(t.p,{children:`Не переключайте registry:`}),`
401
+ `,(0,c.jsxs)(t.ul,{children:[`
402
+ `,(0,c.jsx)(t.li,{children:`во время component render;`}),`
403
+ `,(0,c.jsx)(t.li,{children:`для каждой таблицы;`}),`
404
+ `,(0,c.jsx)(t.li,{children:`перед каждым execute;`}),`
405
+ `,(0,c.jsx)(t.li,{children:`как способ хранить пользовательский state.`}),`
406
+ `]}),`
407
+ `,(0,c.jsx)(t.p,{children:`В тестах замена допустима, но состояние нужно восстанавливать между test cases.`}),`
408
+ `,(0,c.jsx)(t.h3,{id:`уже-скомпилированные-executors`,children:`Уже скомпилированные executors`}),`
409
+ `,(0,c.jsxs)(t.p,{children:[(0,c.jsx)(t.code,{children:`compileTableFormula`}),` получает definition из активного registry и замыкает его функцию. Если после этого установить другой registry, ранее созданный executor продолжит выполнять старую formula function.`]}),`
410
+ `,(0,c.jsx)(t.p,{children:`Новые compile/execute вызовы будут использовать новый активный registry.`}),`
411
+ `,(0,c.jsx)(t.h2,{id:`чтение-активного-реестра`,children:`Чтение активного реестра`}),`
412
+ `,(0,c.jsx)(t.h3,{id:`gettableformulalist`,children:(0,c.jsx)(t.code,{children:`getTableFormulaList()`})}),`
413
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`const formulas = getTableFormulaList();
414
+ `})}),`
415
+ `,(0,c.jsx)(t.p,{children:`Возвращает тот же readonly list активного registry, а не новую копию. Порядок совпадает с порядком definitions, переданных factory.`}),`
416
+ `,(0,c.jsx)(t.p,{children:`Это удобно для UI-каталога:`}),`
417
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`const options = getTableFormulaList().map((formula) => ({
418
+ value: formula.id,
419
+ label: formula.name,
420
+ description: formula.description
421
+ }));
422
+ `})}),`
423
+ `,(0,c.jsx)(t.h3,{id:`gettableformulabyidformulaid`,children:(0,c.jsx)(t.code,{children:`getTableFormulaById(formulaId)`})}),`
424
+ `,(0,c.jsxs)(t.p,{children:[`Trim-ит id и возвращает definition либо `,(0,c.jsx)(t.code,{children:`undefined`}),`:`]}),`
425
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`getTableFormulaById(" sum "); // definition с id "sum"
426
+ getTableFormulaById(""); // undefined
427
+ getTableFormulaById(" "); // undefined
428
+ getTableFormulaById(undefined); // undefined
429
+ getTableFormulaById("unknown"); // undefined
430
+ `})}),`
431
+ `,(0,c.jsx)(t.p,{children:`Возвращается объект из registry, не clone.`}),`
432
+ `,(0,c.jsx)(t.h2,{id:`выполнение-формулы`,children:`Выполнение формулы`}),`
433
+ `,(0,c.jsx)(t.h3,{id:`executetableformulaargs`,children:(0,c.jsx)(t.code,{children:`executeTableFormula(args)`})}),`
434
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`const result = executeTableFormula({
435
+ formulaId: "ratio",
436
+ keys: ["amount", "count"],
437
+ rowData: row
438
+ });
439
+ `})}),`
440
+ `,(0,c.jsx)(t.p,{children:`Функция сначала компилирует formula + keys, затем один раз выполняет полученный executor.`}),`
441
+ `,(0,c.jsx)(t.p,{children:`Результат — discriminated union:`}),`
442
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`type TableFormulaExecutionResult =
443
+ | { ok: true; value: number }
444
+ | {
445
+ ok: false;
446
+ reason: "formula_not_found" | "invalid_result" | "runtime_error";
447
+ };
448
+ `})}),`
449
+ `,(0,c.jsxs)(t.p,{children:[`Всегда проверяйте `,(0,c.jsx)(t.code,{children:`ok`}),` перед чтением `,(0,c.jsx)(t.code,{children:`value`}),`:`]}),`
450
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`const result = executeTableFormula(args);
451
+
452
+ if (result.ok) {
453
+ return result.value;
454
+ }
455
+
456
+ switch (result.reason) {
457
+ case "formula_not_found":
458
+ return "Формула больше не доступна";
459
+ case "invalid_result":
460
+ return "Формула вернула некорректное число";
461
+ case "runtime_error":
462
+ return "Не удалось выполнить формулу";
463
+ }
464
+ `})}),`
465
+ `,(0,c.jsx)(t.h3,{id:`formula_not_found`,children:(0,c.jsx)(t.code,{children:`formula_not_found`})}),`
466
+ `,(0,c.jsx)(t.p,{children:`Возвращается, если:`}),`
467
+ `,(0,c.jsxs)(t.ul,{children:[`
468
+ `,(0,c.jsxs)(t.li,{children:[(0,c.jsx)(t.code,{children:`formulaId`}),` равен `,(0,c.jsx)(t.code,{children:`undefined`}),`;`]}),`
469
+ `,(0,c.jsx)(t.li,{children:`id пуст после trim;`}),`
470
+ `,(0,c.jsx)(t.li,{children:`id отсутствует в активном registry;`}),`
471
+ `,(0,c.jsx)(t.li,{children:`registry ещё не установлен.`}),`
472
+ `]}),`
473
+ `,(0,c.jsx)(t.h3,{id:`invalid_result`,children:(0,c.jsx)(t.code,{children:`invalid_result`})}),`
474
+ `,(0,c.jsx)(t.p,{children:`Formula function выполнилась без исключения, но вернула не конечный number:`}),`
475
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`fn: () => Infinity;
476
+ fn: () => NaN;
477
+ `})}),`
478
+ `,(0,c.jsxs)(t.p,{children:[`Даже если через ошибочный cast функция вернула строку `,(0,c.jsx)(t.code,{children:`"10"`}),`, результат будет invalid: `,(0,c.jsx)(t.code,{children:`Number.isFinite`}),` не выполняет coercion.`]}),`
479
+ `,(0,c.jsx)(t.h3,{id:`runtime_error`,children:(0,c.jsx)(t.code,{children:`runtime_error`})}),`
480
+ `,(0,c.jsx)(t.p,{children:`Formula function выбросила исключение:`}),`
481
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`fn: () => {
482
+ throw new Error("Ошибка расчёта");
483
+ };
484
+ `})}),`
485
+ `,(0,c.jsxs)(t.p,{children:[`Исключение перехватывается. Публичный результат не содержит исходный `,(0,c.jsx)(t.code,{children:`Error`}),`, stack или message. Это безопасная runtime-граница, но не полноценная diagnostics-система. Тестируйте formulas отдельно, чтобы видеть настоящую причину до production.`]}),`
486
+ `,(0,c.jsx)(t.h3,{id:`отсутствующие-keys`,children:`Отсутствующие keys`}),`
487
+ `,(0,c.jsxs)(t.p,{children:[`Если `,(0,c.jsx)(t.code,{children:`keys`}),` не переданы, context имеет пустой mapping. Formula всё равно компилируется, но `,(0,c.jsx)(t.code,{children:`ctx.num(index)`}),` возвращает `,(0,c.jsx)(t.code,{children:`0`}),`:`]}),`
488
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`executeTableFormula({
489
+ formulaId: "sum",
490
+ rowData: { A: 10, B: 20 }
491
+ });
492
+ // sum($0, $1) успешно вернёт 0 + 0 === 0
493
+ `})}),`
494
+ `,(0,c.jsxs)(t.p,{children:[`Это не ошибка execution API. Ошибку недостаточного количества dependencies должен обнаружить `,(0,c.jsx)(t.code,{children:`validateTableFormulaDependencies`}),` до compile.`]}),`
495
+ `,(0,c.jsx)(t.h2,{id:`предварительная-компиляция`,children:`Предварительная компиляция`}),`
496
+ `,(0,c.jsx)(t.h3,{id:`compiletableformulaargs`,children:(0,c.jsx)(t.code,{children:`compileTableFormula(args)`})}),`
497
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`const compiled = compileTableFormula({
498
+ formulaId: "ratio",
499
+ keys: ["amount", "count"]
500
+ });
501
+
502
+ if (!compiled.ok) {
503
+ // Единственная compile-причина — formula_not_found.
504
+ throw new Error("Формула не найдена");
505
+ }
506
+
507
+ const first = compiled.execute({ amount: 100, count: 20 });
508
+ const second = compiled.execute({ amount: 120, count: 40 });
509
+ `})}),`
510
+ `,(0,c.jsx)(t.p,{children:`Compile result:`}),`
511
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`type CompileResult = { ok: true; execute: TableFormulaCompiledExecutor } | { ok: false; reason: "formula_not_found" };
512
+ `})}),`
513
+ `,(0,c.jsxs)(t.p,{children:[(0,c.jsx)(t.code,{children:`CompileResult`}),` показан для понимания, но отдельное именованное публичное type export для него отсутствует. TypeScript выводит тип из возвращаемого значения.`]}),`
514
+ `,(0,c.jsx)(t.h3,{id:`что-фиксируется-при-compile`,children:`Что фиксируется при compile`}),`
515
+ `,(0,c.jsx)(t.p,{children:`Compiler:`}),`
516
+ `,(0,c.jsxs)(t.ul,{children:[`
517
+ `,(0,c.jsx)(t.li,{children:`находит formula definition один раз;`}),`
518
+ `,(0,c.jsxs)(t.li,{children:[`копирует массив `,(0,c.jsx)(t.code,{children:`keys`}),`;`]}),`
519
+ `,(0,c.jsx)(t.li,{children:`создаёт один context object;`}),`
520
+ `,(0,c.jsxs)(t.li,{children:[`возвращает executor `,(0,c.jsx)(t.code,{children:`(rowData) => result`}),`.`]}),`
521
+ `]}),`
522
+ `,(0,c.jsx)(t.p,{children:`Изменение исходного массива keys после compile не влияет на executor. Замена активного registry также не меняет уже найденную formula function.`}),`
523
+ `,(0,c.jsx)(t.h3,{id:`что-происходит-при-каждом-execute`,children:`Что происходит при каждом execute`}),`
524
+ `,(0,c.jsx)(t.p,{children:`Executor:`}),`
525
+ `,(0,c.jsxs)(t.ol,{children:[`
526
+ `,(0,c.jsxs)(t.li,{children:[`записывает ссылку на текущий `,(0,c.jsx)(t.code,{children:`rowData`}),` во внутренний context;`]}),`
527
+ `,(0,c.jsx)(t.li,{children:`синхронно вызывает formula function;`}),`
528
+ `,(0,c.jsxs)(t.li,{children:[`проверяет `,(0,c.jsx)(t.code,{children:`Number.isFinite(result)`}),`;`]}),`
529
+ `,(0,c.jsx)(t.li,{children:`возвращает success или controlled error.`}),`
530
+ `]}),`
531
+ `,(0,c.jsxs)(t.p,{children:[(0,c.jsx)(t.code,{children:`rowData`}),` не копируется.`]}),`
532
+ `,(0,c.jsx)(t.h3,{id:`когда-выбирать-compile`,children:`Когда выбирать compile`}),`
533
+ `,(0,c.jsxs)(t.p,{children:[`Для одной проверки или редкого расчёта допустим `,(0,c.jsx)(t.code,{children:`executeTableFormula`}),`. Для таблицы с десятками/сотнями строк компилируйте один раз на поле и переиспользуйте executor:`]}),`
534
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`const compiled = compileTableFormula({ formulaId, keys });
535
+
536
+ if (compiled.ok) {
537
+ for (const row of rows) {
538
+ const result = compiled.execute(row);
539
+ // обработка результата
540
+ }
541
+ }
542
+ `})}),`
543
+ `,(0,c.jsxs)(t.p,{children:[(0,c.jsx)(t.code,{children:`executeTableFormula`}),` выполняет lookup и compile на каждом вызове, поэтому не является оптимальным горячим путём ячейки.`]}),`
544
+ `,(0,c.jsx)(t.h3,{id:`синхронность-и-повторный-вход`,children:`Синхронность и повторный вход`}),`
545
+ `,(0,c.jsxs)(t.p,{children:[`Compiled executor переиспользует один context с изменяемой внутренней ссылкой на `,(0,c.jsx)(t.code,{children:`rowData`}),`. Это безопасно для обычной синхронной формулы.`]}),`
546
+ `,(0,c.jsxs)(t.p,{children:[`Не делайте formula `,(0,c.jsx)(t.code,{children:`async`}),`, не сохраняйте `,(0,c.jsx)(t.code,{children:`ctx`}),` во внешнем state и не запускайте тот же executor рекурсивно из formula. Такой код нарушает lifecycle переиспользуемого context.`]}),`
547
+ `,(0,c.jsx)(t.h2,{id:`валидация-зависимостей`,children:`Валидация зависимостей`}),`
548
+ `,(0,c.jsx)(t.h3,{id:`validatetableformuladependenciesargs`,children:(0,c.jsx)(t.code,{children:`validateTableFormulaDependencies(args)`})}),`
549
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`const validation = validateTableFormulaDependencies({
550
+ formulaId: "sum",
551
+ dependencies: ["planned", "actual"],
552
+ availableColumnIds: ["planned", "actual", "label"]
553
+ });
554
+ `})}),`
555
+ `,(0,c.jsx)(t.p,{children:`Результат:`}),`
556
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`interface TableFormulaDependenciesValidationResult {
557
+ ok: boolean;
558
+ errors: TableFormulaValidationMessage[];
559
+ warnings: TableFormulaValidationMessage[];
560
+ usage: {
561
+ usedDependencyIndexes: number[];
562
+ usedDependencyIds: string[];
563
+ requiredDependencyCount: number;
564
+ };
565
+ }
566
+ `})}),`
567
+ `,(0,c.jsxs)(t.p,{children:[(0,c.jsx)(t.code,{children:`ok`}),` становится `,(0,c.jsx)(t.code,{children:`false`}),`, только если есть errors. Warnings не запрещают применение config.`]}),`
568
+ `,(0,c.jsx)(t.h3,{id:`что-проверяется`,children:`Что проверяется`}),`
569
+ `,(0,c.jsx)(t.p,{children:`Validator:`}),`
570
+ `,(0,c.jsxs)(t.ol,{children:[`
571
+ `,(0,c.jsx)(t.li,{children:`ищет formula в активном registry;`}),`
572
+ `,(0,c.jsxs)(t.li,{children:[`проверяет, что каждый dependency id входит в `,(0,c.jsx)(t.code,{children:`availableColumnIds`}),`;`]}),`
573
+ `,(0,c.jsx)(t.li,{children:`запускает formula на положительных synthetic values;`}),`
574
+ `,(0,c.jsx)(t.li,{children:`запускает formula на отрицательных synthetic values;`}),`
575
+ `,(0,c.jsx)(t.li,{children:`через instrumentation собирает прочитанные indexes;`}),`
576
+ `,(0,c.jsx)(t.li,{children:`обнаруживает обращения за пределы dependencies;`}),`
577
+ `,(0,c.jsx)(t.li,{children:`сообщает неиспользованные dependencies;`}),`
578
+ `,(0,c.jsx)(t.li,{children:`сообщает отсутствие чтения dependencies;`}),`
579
+ `,(0,c.jsx)(t.li,{children:`сообщает исключение на synthetic data.`}),`
580
+ `]}),`
581
+ `,(0,c.jsx)(t.h3,{id:`errors`,children:`Errors`}),`
582
+ `,(0,c.jsxs)(t.table,{children:[(0,c.jsx)(t.thead,{children:(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.th,{children:(0,c.jsx)(t.code,{children:`code`})}),(0,c.jsx)(t.th,{children:`Условие`})]})}),(0,c.jsxs)(t.tbody,{children:[(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`formula_not_found`})}),(0,c.jsx)(t.td,{children:`Formula id отсутствует в registry`})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`dependency_not_available`})}),(0,c.jsx)(t.td,{children:`Dependency id отсутствует среди доступных колонок`})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`dependency_index_out_of_range`})}),(0,c.jsx)(t.td,{children:`Formula прочитала index, для которого dependency не передан`})]})]})]}),`
583
+ `,(0,c.jsx)(t.h3,{id:`warnings`,children:`Warnings`}),`
584
+ `,(0,c.jsxs)(t.table,{children:[(0,c.jsx)(t.thead,{children:(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.th,{children:(0,c.jsx)(t.code,{children:`code`})}),(0,c.jsx)(t.th,{children:`Условие`})]})}),(0,c.jsxs)(t.tbody,{children:[(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`unused_dependencies`})}),(0,c.jsx)(t.td,{children:`Выбраны dependencies, которые formula не прочитала на test passes`})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`formula_does_not_use_dependencies`})}),(0,c.jsx)(t.td,{children:`Formula не прочитала ни одного index`})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`formula_runtime_error`})}),(0,c.jsx)(t.td,{children:`Formula выбросила исключение на synthetic data`})]})]})]}),`
585
+ `,(0,c.jsx)(t.h3,{id:`usage`,children:`Usage`}),`
586
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`validation.usage.usedDependencyIndexes; // например [0, 1]
587
+ validation.usage.usedDependencyIds; // например ["planned", "actual"]
588
+ validation.usage.requiredDependencyCount; // 2
589
+ `})}),`
590
+ `,(0,c.jsxs)(t.p,{children:[(0,c.jsx)(t.code,{children:`requiredDependencyCount`}),` равен `,(0,c.jsx)(t.code,{children:`максимальный использованный index + 1`}),`.`]}),`
591
+ `,(0,c.jsx)(t.p,{children:`Это полезно редактору:`}),`
592
+ `,(0,c.jsxs)(t.ul,{children:[`
593
+ `,(0,c.jsx)(t.li,{children:`показать, сколько arguments ожидает formula;`}),`
594
+ `,(0,c.jsx)(t.li,{children:`подсветить лишние dependencies;`}),`
595
+ `,(0,c.jsx)(t.li,{children:`объяснить missing index;`}),`
596
+ `,(0,c.jsx)(t.li,{children:`построить diagnostics без анализа JavaScript source.`}),`
597
+ `]}),`
598
+ `,(0,c.jsxs)(t.h3,{id:`availablecolumnids-нужно-передавать-явно`,children:[(0,c.jsx)(t.code,{children:`availableColumnIds`}),` нужно передавать явно`]}),`
599
+ `,(0,c.jsxs)(t.p,{children:[`По умолчанию список доступных колонок пуст. Если передать dependencies, но не передать `,(0,c.jsx)(t.code,{children:`availableColumnIds`}),`, каждый dependency будет считаться недоступным:`]}),`
600
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`validateTableFormulaDependencies({
601
+ formulaId: "sum",
602
+ dependencies: ["A", "B"]
603
+ });
604
+ // dependency_not_available для A и B
605
+ `})}),`
606
+ `,(0,c.jsx)(t.p,{children:`Если вы хотите проверить реальную конфигурацию колонки, передайте полный разрешённый набор field ids.`}),`
607
+ `,(0,c.jsx)(t.h3,{id:`validator-выполняет-formula-function`,children:`Validator выполняет formula function`}),`
608
+ `,(0,c.jsxs)(t.p,{children:[`Validation — не статический анализ. Она действительно вызывает `,(0,c.jsx)(t.code,{children:`fn`}),` как минимум два раза. Поэтому formula обязана быть чистой:`]}),`
609
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`// Неправильно: validation и каждый row execution меняют внешний state.
610
+ fn: (ctx) => {
611
+ counter += 1;
612
+ return ctx.num(0);
613
+ };
614
+ `})}),`
615
+ `,(0,c.jsx)(t.p,{children:`Не выполняйте в formula:`}),`
616
+ `,(0,c.jsxs)(t.ul,{children:[`
617
+ `,(0,c.jsx)(t.li,{children:`сетевые запросы;`}),`
618
+ `,(0,c.jsx)(t.li,{children:`запись в store;`}),`
619
+ `,(0,c.jsx)(t.li,{children:`DOM-операции;`}),`
620
+ `,(0,c.jsxs)(t.li,{children:[`mutation `,(0,c.jsx)(t.code,{children:`rowData`}),`;`]}),`
621
+ `,(0,c.jsx)(t.li,{children:`logging на каждый вызов;`}),`
622
+ `,(0,c.jsx)(t.li,{children:`генерацию случайных значений;`}),`
623
+ `,(0,c.jsx)(t.li,{children:`чтение текущего времени как части результата.`}),`
624
+ `]}),`
625
+ `,(0,c.jsx)(t.h3,{id:`ограничения-validation`,children:`Ограничения validation`}),`
626
+ `,(0,c.jsx)(t.p,{children:`Два synthetic passes повышают шанс пройти разные branches, но не доказывают корректность для всех данных.`}),`
627
+ `,(0,c.jsx)(t.p,{children:`Validator не гарантирует:`}),`
628
+ `,(0,c.jsxs)(t.ul,{children:[`
629
+ `,(0,c.jsx)(t.li,{children:`выполнение каждой условной ветки;`}),`
630
+ `,(0,c.jsx)(t.li,{children:`корректность business formula;`}),`
631
+ `,(0,c.jsx)(t.li,{children:`отсутствие деления на ноль на реальных данных;`}),`
632
+ `,(0,c.jsx)(t.li,{children:`конечный numeric result;`}),`
633
+ `,(0,c.jsxs)(t.li,{children:[`корректность `,(0,c.jsx)(t.code,{children:`args`}),` metadata;`]}),`
634
+ `,(0,c.jsx)(t.li,{children:`уникальность/непустоту dependency ids;`}),`
635
+ `,(0,c.jsxs)(t.li,{children:[`наличие fields в реальном `,(0,c.jsx)(t.code,{children:`rowData`}),` во время execute.`]}),`
636
+ `]}),`
637
+ `,(0,c.jsxs)(t.p,{children:[`Особенно важно: validation игнорирует возвращаемое число и проверяет только runtime exception. Formula, возвращающая `,(0,c.jsx)(t.code,{children:`Infinity`}),`, может пройти dependency validation, но execution затем вернёт `,(0,c.jsx)(t.code,{children:`invalid_result`}),`.`]}),`
638
+ `,(0,c.jsx)(t.p,{children:`Поэтому validator дополняет, а не заменяет unit-tests formula.`}),`
639
+ `,(0,c.jsx)(t.h3,{id:`условные-dependencies`,children:`Условные dependencies`}),`
640
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`fn: (ctx) => (ctx.num(0) > 0 ? ctx.num(1) : ctx.num(2));
641
+ `})}),`
642
+ `,(0,c.jsxs)(t.p,{children:[`Положительный и отрицательный passes могут обнаружить indexes `,(0,c.jsx)(t.code,{children:`1`}),` и `,(0,c.jsx)(t.code,{children:`2`}),`, но сложные branches всё равно способны скрыть dependency. Документируйте полный positional contract в `,(0,c.jsx)(t.code,{children:`args`}),` и тестируйте все ветки самостоятельно.`]}),`
643
+ `,(0,c.jsx)(t.h3,{id:`повторяющиеся-ids`,children:`Повторяющиеся ids`}),`
644
+ `,(0,c.jsx)(t.p,{children:`Validator не дедуплицирует dependencies. Если передать один field id в нескольких позициях, оба indexes будут читать одно и то же свойство rowData. Обычно это ошибка конфигурации, хотя технически она допустима.`}),`
645
+ `,(0,c.jsx)(t.h2,{id:`интеграция-с-formatter-pipeline`,children:`Интеграция с formatter pipeline`}),`
646
+ `,(0,c.jsxs)(t.p,{children:[`Модуль `,(0,c.jsx)(t.code,{children:`formatters/pipeline`}),` умеет выполнять table formula до остальных шагов форматирования.`]}),`
647
+ `,(0,c.jsx)(t.p,{children:`Минимальный runtime field:`}),`
648
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`import {
649
+ compileFormattersPipelineRuntime,
650
+ formatPipelineDisplayValue,
651
+ type FormattersPipelineRuntimeField
652
+ } from "@ryuzaki13/react-foundation-lib/formatters";
653
+
654
+ const field: FormattersPipelineRuntimeField = {
655
+ id: "total",
656
+ role: "measure",
657
+ type: "decimal",
658
+ formulaId: "sum",
659
+ formulaDependencies: ["planned", "actual"],
660
+ purelyDerived: true,
661
+ emptyWhenZero: false
662
+ };
663
+
664
+ compileFormattersPipelineRuntime(field);
665
+
666
+ const display = formatPipelineDisplayValue({
667
+ field,
668
+ rawValue: undefined,
669
+ rowData: {
670
+ planned: 100,
671
+ actual: 25
672
+ },
673
+ rowKind: "plain"
674
+ });
675
+ `})}),`
676
+ `,(0,c.jsx)(t.p,{children:`Runtime flow:`}),`
677
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-text`,children:`rawValue
678
+ ↓ table formula из /formulas
679
+ ↓ formatter pipeline steps
680
+ ↓ typed formatting / fallback
681
+ display result
682
+ `})}),`
683
+ `,(0,c.jsx)(t.p,{children:`Важно:`}),`
684
+ `,(0,c.jsxs)(t.ul,{children:[`
685
+ `,(0,c.jsxs)(t.li,{children:[`registry должен быть установлен до `,(0,c.jsx)(t.code,{children:`compileFormattersPipelineRuntime`}),`;`]}),`
686
+ `,(0,c.jsxs)(t.li,{children:[`поле должно содержать все `,(0,c.jsx)(t.code,{children:`formulaDependencies`}),` в `,(0,c.jsx)(t.code,{children:`rowData`}),`;`]}),`
687
+ `,(0,c.jsx)(t.li,{children:`pipeline compiler сохраняет formula executor в самом field object;`}),`
688
+ `,(0,c.jsx)(t.li,{children:`invalid/missing formula не выбрасывается при display execution;`}),`
689
+ `,(0,c.jsxs)(t.li,{children:[`при `,(0,c.jsx)(t.code,{children:`purelyDerived: true`}),` ошибка формулы даёт пустое значение;`]}),`
690
+ `,(0,c.jsxs)(t.li,{children:[`без `,(0,c.jsx)(t.code,{children:`purelyDerived`}),` ошибка откатывается к `,(0,c.jsx)(t.code,{children:`rawValue`}),`;`]}),`
691
+ `,(0,c.jsxs)(t.li,{children:[(0,c.jsx)(t.code,{children:`emptyWhenZero`}),` может скрыть успешный нулевой source result.`]}),`
692
+ `]}),`
693
+ `,(0,c.jsxs)(t.p,{children:[`Полный lifecycle и mutation-контракт runtime compiler описаны в `,(0,c.jsx)(t.a,{href:`../formatters/pipeline/README.mdx`,children:`README formatter pipeline`}),`.`]}),`
694
+ `,(0,c.jsx)(t.h3,{id:`зависимости-должны-попасть-в-данные-строки`,children:`Зависимости должны попасть в данные строки`}),`
695
+ `,(0,c.jsxs)(t.p,{children:[(0,c.jsx)(t.code,{children:`formulaDependencies`}),` — это не request builder. Сам модуль не добавляет fields в OData select и не загружает их.`]}),`
696
+ `,(0,c.jsx)(t.p,{children:`Owner таблицы/query обязан:`}),`
697
+ `,(0,c.jsxs)(t.ol,{children:[`
698
+ `,(0,c.jsx)(t.li,{children:`проверить dependency ids относительно доступных columns;`}),`
699
+ `,(0,c.jsx)(t.li,{children:`включить нужные fields в серверный запрос или локальный row model;`}),`
700
+ `,(0,c.jsxs)(t.li,{children:[`передать полный `,(0,c.jsx)(t.code,{children:`rowData`}),` formatter runtime.`]}),`
701
+ `]}),`
702
+ `,(0,c.jsxs)(t.p,{children:[`Иначе `,(0,c.jsx)(t.code,{children:`ctx.value`}),` вернёт `,(0,c.jsx)(t.code,{children:`undefined`}),`, а `,(0,c.jsx)(t.code,{children:`ctx.num`}),` — `,(0,c.jsx)(t.code,{children:`0`}),`, что может выглядеть как успешный, но неверный расчёт.`]}),`
703
+ `,(0,c.jsx)(t.h2,{id:`отличие-от-row-based-formatter`,children:`Отличие от row-based formatter`}),`
704
+ `,(0,c.jsxs)(t.p,{children:[`В пакете есть похожий, но отдельный реестр `,(0,c.jsx)(t.code,{children:`formatters/rowBased`}),`.`]}),`
705
+ `,(0,c.jsxs)(t.table,{children:[(0,c.jsx)(t.thead,{children:(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.th,{children:`Свойство`}),(0,c.jsxs)(t.th,{children:[`Table formula (`,(0,c.jsx)(t.code,{children:`/formulas`}),`)`]}),(0,c.jsxs)(t.th,{children:[`Row-based formatter (`,(0,c.jsx)(t.code,{children:`/formatters`}),`)`]})]})}),(0,c.jsxs)(t.tbody,{children:[(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:`Основная задача`}),(0,c.jsx)(t.td,{children:`Рассчитать numeric value колонки`}),(0,c.jsx)(t.td,{children:`Подменить текущее значение внутри formatter pipeline`})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:`Результат function`}),(0,c.jsxs)(t.td,{children:[`Только `,(0,c.jsx)(t.code,{children:`number`})]}),(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`unknown`})})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:`Context`}),(0,c.jsxs)(t.td,{children:[(0,c.jsx)(t.code,{children:`key`}),`, `,(0,c.jsx)(t.code,{children:`value`}),`, `,(0,c.jsx)(t.code,{children:`num`})]}),(0,c.jsxs)(t.td,{children:[`дополнительно `,(0,c.jsx)(t.code,{children:`rawValue`}),`, `,(0,c.jsx)(t.code,{children:`rowData`}),`, `,(0,c.jsx)(t.code,{children:`columnId`})]})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:`Место выполнения`}),(0,c.jsx)(t.td,{children:`До formatter pipeline`}),(0,c.jsxs)(t.td,{children:[`Шаг `,(0,c.jsx)(t.code,{children:`rowBasedOverride`}),` внутри pipeline`]})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:`Конфиг поля`}),(0,c.jsxs)(t.td,{children:[(0,c.jsx)(t.code,{children:`formulaId`}),`, `,(0,c.jsx)(t.code,{children:`formulaDependencies`})]}),(0,c.jsxs)(t.td,{children:[`Pipeline step с `,(0,c.jsx)(t.code,{children:`formulaId`}),`, `,(0,c.jsx)(t.code,{children:`dependencyIds`})]})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:`Registry`}),(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`configureTableFormulaRegistry`})}),(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`configureRowBasedFormatterRegistry`})})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:`Error result`}),(0,c.jsxs)(t.td,{children:[(0,c.jsx)(t.code,{children:`formula_not_found`}),`, `,(0,c.jsx)(t.code,{children:`invalid_result`}),`, `,(0,c.jsx)(t.code,{children:`runtime_error`})]}),(0,c.jsxs)(t.td,{children:[`Управляется `,(0,c.jsx)(t.code,{children:`fallbackToRaw`}),` pipeline step`]})]})]})]}),`
706
+ `,(0,c.jsx)(t.p,{children:`Не используйте одинаковый id как доказательство, что formula автоматически доступна в обоих реестрах. Это независимые catalogs и APIs.`}),`
707
+ `,(0,c.jsx)(t.p,{children:`Простое правило:`}),`
708
+ `,(0,c.jsxs)(t.ul,{children:[`
709
+ `,(0,c.jsx)(t.li,{children:`вычисляемая числовая колонка → table formula;`}),`
710
+ `,(0,c.jsx)(t.li,{children:`contextual display override внутри pipeline → row-based formatter.`}),`
711
+ `]}),`
712
+ `,(0,c.jsx)(t.h2,{id:`архитектура-и-безопасность`,children:`Архитектура и безопасность`}),`
713
+ `,(0,c.jsx)(t.h3,{id:`где-размещать-definitions`,children:`Где размещать definitions`}),`
714
+ `,(0,c.jsx)(t.p,{children:`Foundation-пакет предоставляет только механизм. Конкретные business formulas принадлежат host-приложению:`}),`
715
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-text`,children:`app composition / registries
716
+ ├─ formula definitions
717
+ ├─ единый ordered catalog
718
+ ├─ createTableFormulaRegistry
719
+ └─ configureTableFormulaRegistry при bootstrap
720
+ `})}),`
721
+ `,(0,c.jsx)(t.p,{children:`Формулу, специфичную для одной feature/entity, не следует переносить в foundation только потому, что она использует общий runtime.`}),`
722
+ `,(0,c.jsx)(t.h3,{id:`почему-нет-formula-strings`,children:`Почему нет formula strings`}),`
723
+ `,(0,c.jsxs)(t.p,{children:[`Конфигурация вида `,(0,c.jsx)(t.code,{children:`"$0 + $1"`}),` не исполняется как код. Это осознанная граница:`]}),`
724
+ `,(0,c.jsxs)(t.ul,{children:[`
725
+ `,(0,c.jsxs)(t.li,{children:[`нет `,(0,c.jsx)(t.code,{children:`eval`}),`;`]}),`
726
+ `,(0,c.jsx)(t.li,{children:`нет dynamic code generation;`}),`
727
+ `,(0,c.jsx)(t.li,{children:`нет необходимости доверять тексту из БД;`}),`
728
+ `,(0,c.jsx)(t.li,{children:`TypeScript проверяет написанные definitions;`}),`
729
+ `,(0,c.jsx)(t.li,{children:`обычные unit-tests видят функцию напрямую.`}),`
730
+ `]}),`
731
+ `,(0,c.jsxs)(t.p,{children:[(0,c.jsx)(t.code,{children:`description`}),` может содержать формулу для человека, но runtime выполняет только `,(0,c.jsx)(t.code,{children:`fn`}),`, заранее включённую разработчиком в registry.`]}),`
732
+ `,(0,c.jsx)(t.h3,{id:`доверенный-код-всё-равно-требует-дисциплины`,children:`Доверенный код всё равно требует дисциплины`}),`
733
+ `,(0,c.jsxs)(t.p,{children:[`Модуль перехватывает exceptions и invalid numbers, но не может отменить уже выполненный side effect. Если formula изменила store, отправила запрос или мутировала rowData, возврат `,(0,c.jsx)(t.code,{children:`runtime_error`}),` не откатит это действие.`]}),`
734
+ `,(0,c.jsx)(t.p,{children:`Формулы должны быть чистыми вычислениями.`}),`
735
+ `,(0,c.jsx)(t.h3,{id:`стабильность-ids`,children:`Стабильность ids`}),`
736
+ `,(0,c.jsxs)(t.p,{children:[`Если id сохраняется в конфигурации пользователя, его переименование разорвёт связь и даст `,(0,c.jsx)(t.code,{children:`formula_not_found`}),`. Миграцию сохранённых configs должен выполнять владелец config boundary. Не добавляйте silent alias в foundation без отдельного требования.`]}),`
737
+ `,(0,c.jsx)(t.h2,{id:`тестирование`,children:`Тестирование`}),`
738
+ `,(0,c.jsx)(t.h3,{id:`изоляция-глобального-реестра`,children:`Изоляция глобального реестра`}),`
739
+ `,(0,c.jsx)(t.p,{children:`Registry не имеет отдельной reset-функции. Для теста установите нужный registry, а после теста верните пустой или application registry:`}),`
740
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`import { afterEach, beforeEach } from "vitest";
741
+ import { configureTableFormulaRegistry, createTableFormulaRegistry } from "@ryuzaki13/react-foundation-lib/formulas";
742
+
743
+ const testRegistry = createTableFormulaRegistry([sumFormula]);
744
+
745
+ beforeEach(() => {
746
+ configureTableFormulaRegistry(testRegistry);
747
+ });
748
+
749
+ afterEach(() => {
750
+ configureTableFormulaRegistry(createTableFormulaRegistry([]));
751
+ });
752
+ `})}),`
753
+ `,(0,c.jsx)(t.p,{children:`Если тесты выполняются параллельно в одном module instance и меняют registry, централизуйте setup или избегайте concurrent cases.`}),`
754
+ `,(0,c.jsx)(t.h3,{id:`unit-test-formula-без-registry`,children:`Unit-test formula без registry`}),`
755
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`import { createTableFormulaContext } from "@ryuzaki13/react-foundation-lib/formulas";
756
+
757
+ const context = createTableFormulaContext({
758
+ rowData: { A: 100, B: 25 },
759
+ keys: ["A", "B"]
760
+ });
761
+
762
+ expect(sumFormula.fn(context)).toBe(125);
763
+ `})}),`
764
+ `,(0,c.jsx)(t.p,{children:`Этот тест показывает настоящую thrown error и удобен для business cases.`}),`
765
+ `,(0,c.jsx)(t.h3,{id:`integration-test-через-public-runtime`,children:`Integration-test через public runtime`}),`
766
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`expect(
767
+ executeTableFormula({
768
+ formulaId: "sum",
769
+ rowData: { A: 100, B: 25 },
770
+ keys: ["A", "B"]
771
+ })
772
+ ).toEqual({ ok: true, value: 125 });
773
+ `})}),`
774
+ `,(0,c.jsx)(t.p,{children:`Так проверяются registry lookup, context mapping и result boundary.`}),`
775
+ `,(0,c.jsx)(t.h3,{id:`минимальная-матрица`,children:`Минимальная матрица`}),`
776
+ `,(0,c.jsx)(t.p,{children:`Для каждой нетривиальной formula проверяйте:`}),`
777
+ `,(0,c.jsxs)(t.ul,{children:[`
778
+ `,(0,c.jsx)(t.li,{children:`обычные положительные values;`}),`
779
+ `,(0,c.jsx)(t.li,{children:`нули;`}),`
780
+ `,(0,c.jsx)(t.li,{children:`отрицательные values;`}),`
781
+ `,(0,c.jsx)(t.li,{children:`отсутствующие properties;`}),`
782
+ `,(0,c.jsx)(t.li,{children:`строки вместо numbers, если transport это допускает;`}),`
783
+ `,(0,c.jsx)(t.li,{children:`деление на ноль;`}),`
784
+ `,(0,c.jsx)(t.li,{children:`порядок dependencies;`}),`
785
+ `,(0,c.jsx)(t.li,{children:`каждый conditional branch;`}),`
786
+ `,(0,c.jsx)(t.li,{children:`конечность результата;`}),`
787
+ `,(0,c.jsx)(t.li,{children:`validation с недостаточными и лишними dependencies.`}),`
788
+ `]}),`
789
+ `,(0,c.jsx)(t.p,{children:`Для registry отдельно проверяйте уникальность ids и expected order каталога.`}),`
790
+ `,(0,c.jsx)(t.h2,{id:`производительность`,children:`Производительность`}),`
791
+ `,(0,c.jsx)(t.h3,{id:`горячий-путь-таблицы`,children:`Горячий путь таблицы`}),`
792
+ `,(0,c.jsx)(t.p,{children:`Главная оптимизация — предварительная компиляция:`}),`
793
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-text`,children:`медленнее: executeTableFormula для каждой ячейки
794
+ быстрее: compileTableFormula один раз → execute(rowData) для каждой строки
795
+ `})}),`
796
+ `,(0,c.jsx)(t.p,{children:`Compiled executor переиспользует context и не делает registry lookup на каждую строку.`}),`
797
+ `,(0,c.jsx)(t.p,{children:`Formatter pipeline уже использует этот подход: runtime field компилируется на construction-stage.`}),`
798
+ `,(0,c.jsx)(t.h3,{id:`внутренние-benchmark-helpers`,children:`Внутренние benchmark helpers`}),`
799
+ `,(0,c.jsxs)(t.p,{children:[`В исходном каталоге существуют `,(0,c.jsx)(t.code,{children:`runTableFormulaRuntimePerf`}),` и `,(0,c.jsx)(t.code,{children:`runTableFormulaV2PrecompilePerf`}),`, но `,(0,c.jsx)(t.code,{children:`src/formulas/index.ts`}),` их не экспортирует. Они предназначены для внутреннего perf-теста пакета и не являются публичным API `,(0,c.jsx)(t.code,{children:`@ryuzaki13/react-foundation-lib/formulas`}),`.`]}),`
800
+ `,(0,c.jsxs)(t.p,{children:[`Не делайте private import. Для измерения своего consumer-кода используйте собственный benchmark вокруг публичного `,(0,c.jsx)(t.code,{children:`compileTableFormula`}),`.`]}),`
801
+ `,(0,c.jsx)(t.p,{children:`Абсолютные timings зависят от устройства и runtime; сравнивайте несколько прогретых запусков и относительную разницу.`}),`
802
+ `,(0,c.jsx)(t.h2,{id:`частые-ошибки`,children:`Частые ошибки`}),`
803
+ `,(0,c.jsx)(t.h3,{id:`не-установить-registry-до-runtime`,children:`Не установить registry до runtime`}),`
804
+ `,(0,c.jsxs)(t.p,{children:[`Результатом будет `,(0,c.jsx)(t.code,{children:`formula_not_found`}),`, даже если definition существует в файле приложения, но не был передан `,(0,c.jsx)(t.code,{children:`configureTableFormulaRegistry`}),`.`]}),`
805
+ `,(0,c.jsx)(t.h3,{id:`перепутать-порядок-dependencies`,children:`Перепутать порядок dependencies`}),`
806
+ `,(0,c.jsxs)(t.p,{children:[`Indexes не знают бизнес-названий. `,(0,c.jsx)(t.code,{children:`[A, B]`}),` и `,(0,c.jsx)(t.code,{children:`[B, A]`}),` — разные формулы для вычитания/деления.`]}),`
807
+ `,(0,c.jsxs)(t.h3,{id:`считать-ctxnum-строгим-parser`,children:[`Считать `,(0,c.jsx)(t.code,{children:`ctx.num`}),` строгим parser`]}),`
808
+ `,(0,c.jsxs)(t.p,{children:[(0,c.jsx)(t.code,{children:`null`}),`, пустая строка и `,(0,c.jsx)(t.code,{children:`false`}),` превращаются в `,(0,c.jsx)(t.code,{children:`0`}),`, а `,(0,c.jsx)(t.code,{children:`true`}),` — в `,(0,c.jsx)(t.code,{children:`1`}),`. Локализованное `,(0,c.jsx)(t.code,{children:`"1 234,5"`}),` также даёт `,(0,c.jsx)(t.code,{children:`0`}),`.`]}),`
809
+ `,(0,c.jsx)(t.h3,{id:`считать-missing-property-runtime-ошибкой`,children:`Считать missing property runtime-ошибкой`}),`
810
+ `,(0,c.jsxs)(t.p,{children:[(0,c.jsx)(t.code,{children:`ctx.value`}),` возвращает `,(0,c.jsx)(t.code,{children:`undefined`}),`, а `,(0,c.jsx)(t.code,{children:`ctx.num`}),` — `,(0,c.jsx)(t.code,{children:`0`}),`. Поэтому неполный query может silently изменить результат. Проверяйте request dependencies у владельца таблицы.`]}),`
811
+ `,(0,c.jsx)(t.h3,{id:`игнорировать-execution-result`,children:`Игнорировать execution result`}),`
812
+ `,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`// Неправильно: value отсутствует в error branch.
813
+ // const value = executeTableFormula(args).value;
814
+
815
+ const result = executeTableFormula(args);
816
+ const value = result.ok ? result.value : 0;
817
+ `})}),`
818
+ `,(0,c.jsxs)(t.p,{children:[`Fallback `,(0,c.jsx)(t.code,{children:`0`}),` в примере — решение consumer-а, а не рекомендация для всех бизнес-сценариев.`]}),`
819
+ `,(0,c.jsx)(t.h3,{id:`ожидать-что-validator-не-выполняет-formula`,children:`Ожидать, что validator не выполняет formula`}),`
820
+ `,(0,c.jsx)(t.p,{children:`Он вызывает function на synthetic data. Любой side effect произойдёт уже при открытии/проверке редактора.`}),`
821
+ `,(0,c.jsxs)(t.h3,{id:`ожидать-что-validation-найдёт-infinity`,children:[`Ожидать, что validation найдёт `,(0,c.jsx)(t.code,{children:`Infinity`})]}),`
822
+ `,(0,c.jsxs)(t.p,{children:[`Dependency validator не проверяет returned value. `,(0,c.jsx)(t.code,{children:`compile/execute`}),` проверяют и возвращают `,(0,c.jsx)(t.code,{children:`invalid_result`}),`.`]}),`
823
+ `,(0,c.jsx)(t.h3,{id:`регистрировать-formulas-во-время-render`,children:`Регистрировать formulas во время render`}),`
824
+ `,(0,c.jsx)(t.p,{children:`Это глобальная application configuration. Настраивайте её до render и compile runtime.`}),`
825
+ `,(0,c.jsxs)(t.h3,{id:`использовать-async-formula`,children:[`Использовать `,(0,c.jsx)(t.code,{children:`async`}),` formula`]}),`
826
+ `,(0,c.jsxs)(t.p,{children:[`Promise не является конечным number и даст `,(0,c.jsx)(t.code,{children:`invalid_result`}),`; сохранённый context также не рассчитан на чтение после `,(0,c.jsx)(t.code,{children:`await`}),`.`]}),`
827
+ `,(0,c.jsx)(t.h3,{id:`хранить-function-в-json`,children:`Хранить function в JSON`}),`
828
+ `,(0,c.jsxs)(t.p,{children:[`Сохраняйте только `,(0,c.jsx)(t.code,{children:`formulaId`}),` и dependency ids. Function определяется доверенным application bundle.`]}),`
829
+ `,(0,c.jsx)(t.h3,{id:`путать-table-formula-и-row-based-formatter`,children:`Путать table formula и row-based formatter`}),`
830
+ `,(0,c.jsx)(t.p,{children:`Они используют разные registries, contexts и этапы runtime.`}),`
831
+ `,(0,c.jsx)(t.h2,{id:`api-справка`,children:`API-справка`}),`
832
+ `,(0,c.jsx)(t.h3,{id:`runtime-functions`,children:`Runtime functions`}),`
833
+ `,(0,c.jsxs)(t.table,{children:[(0,c.jsx)(t.thead,{children:(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.th,{children:`API`}),(0,c.jsx)(t.th,{children:`Назначение`}),(0,c.jsx)(t.th,{children:`Важное поведение`})]})}),(0,c.jsxs)(t.tbody,{children:[(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`createTableFormulaContext`})}),(0,c.jsx)(t.td,{children:`Создать context вручную`}),(0,c.jsxs)(t.td,{children:[`Копирует keys, но не rowData; `,(0,c.jsx)(t.code,{children:`num`}),` использует `,(0,c.jsx)(t.code,{children:`Number`})]})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`createTableFormulaRegistry`})}),(0,c.jsx)(t.td,{children:`Собрать нормализованный registry`}),(0,c.jsxs)(t.td,{children:[`Бросает `,(0,c.jsx)(t.code,{children:`Error`}),` для пустого/повторного id`]})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`configureTableFormulaRegistry`})}),(0,c.jsx)(t.td,{children:`Установить активный registry`}),(0,c.jsx)(t.td,{children:`Полностью заменяет module-level registry`})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`getTableFormulaList`})}),(0,c.jsx)(t.td,{children:`Получить ordered catalog`}),(0,c.jsx)(t.td,{children:`Возвращает тот же readonly list`})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`getTableFormulaById`})}),(0,c.jsx)(t.td,{children:`Найти definition`}),(0,c.jsxs)(t.td,{children:[`Trim id; `,(0,c.jsx)(t.code,{children:`undefined`}),` для пустого/неизвестного`]})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`compileTableFormula`})}),(0,c.jsx)(t.td,{children:`Подготовить reusable executor`}),(0,c.jsx)(t.td,{children:`Фиксирует formula и копирует keys`})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`executeTableFormula`})}),(0,c.jsx)(t.td,{children:`Compile + один execute`}),(0,c.jsx)(t.td,{children:`Возвращает controlled result, не бросает formula error`})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`validateTableFormulaDependencies`})}),(0,c.jsx)(t.td,{children:`Проверить mapping dependencies`}),(0,c.jsx)(t.td,{children:`Дважды исполняет formula на synthetic data`})]})]})]}),`
834
+ `,(0,c.jsx)(t.h3,{id:`публичные-typescript-типы`,children:`Публичные TypeScript-типы`}),`
835
+ `,(0,c.jsxs)(t.table,{children:[(0,c.jsx)(t.thead,{children:(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.th,{children:`Тип`}),(0,c.jsx)(t.th,{children:`Назначение`})]})}),(0,c.jsxs)(t.tbody,{children:[(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`TableFormulaRowData`})}),(0,c.jsxs)(t.td,{children:[`Строка `,(0,c.jsx)(t.code,{children:`Record<string, unknown>`})]})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`TableFormulaContext`})}),(0,c.jsxs)(t.td,{children:[`Методы `,(0,c.jsx)(t.code,{children:`key`}),`, `,(0,c.jsx)(t.code,{children:`value`}),`, `,(0,c.jsx)(t.code,{children:`num`})]})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`TableFormulaFn`})}),(0,c.jsxs)(t.td,{children:[`Синхронная function `,(0,c.jsx)(t.code,{children:`context → number`})]})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`TableFormulaDefinition`})}),(0,c.jsx)(t.td,{children:`Metadata и function одной formula`})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`TableFormulaRegistry`})}),(0,c.jsxs)(t.td,{children:[`Readonly `,(0,c.jsx)(t.code,{children:`list`}),` + `,(0,c.jsx)(t.code,{children:`byId`})]})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`TableFormulaExecutionResult`})}),(0,c.jsx)(t.td,{children:`Success/error результат execute`})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`TableFormulaCompiledExecutor`})}),(0,c.jsxs)(t.td,{children:[`Переиспользуемый `,(0,c.jsx)(t.code,{children:`(rowData) → result`})]})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`TableFormulaValidationMessage`})}),(0,c.jsxs)(t.td,{children:[(0,c.jsx)(t.code,{children:`{ code, message }`}),` validation diagnostics`]})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`TableFormulaDependenciesValidationResult`})}),(0,c.jsx)(t.td,{children:`Errors, warnings и usage dependencies`})]})]})]}),`
836
+ `,(0,c.jsxs)(t.p,{children:[(0,c.jsx)(t.code,{children:`ValidationCode`}),`, instrumentation type и compile-result type не экспортируются как именованные публичные типы. Их конкретные значения доступны через публичные function signatures и unions, описанные выше.`]}),`
837
+ `,(0,c.jsx)(t.h3,{id:`причины-execution-error`,children:`Причины execution error`}),`
838
+ `,(0,c.jsxs)(t.table,{children:[(0,c.jsx)(t.thead,{children:(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.th,{children:`Reason`}),(0,c.jsx)(t.th,{children:`Значение`})]})}),(0,c.jsxs)(t.tbody,{children:[(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`formula_not_found`})}),(0,c.jsx)(t.td,{children:`Formula отсутствует в активном registry`})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`invalid_result`})}),(0,c.jsx)(t.td,{children:`Function вернула не конечный number`})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`runtime_error`})}),(0,c.jsx)(t.td,{children:`Function выбросила исключение`})]})]})]}),`
839
+ `,(0,c.jsx)(t.h3,{id:`validation-codes`,children:`Validation codes`}),`
840
+ `,(0,c.jsxs)(t.table,{children:[(0,c.jsx)(t.thead,{children:(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.th,{children:`Code`}),(0,c.jsx)(t.th,{children:`Severity`})]})}),(0,c.jsxs)(t.tbody,{children:[(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`formula_not_found`})}),(0,c.jsx)(t.td,{children:`error`})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`dependency_index_out_of_range`})}),(0,c.jsx)(t.td,{children:`error`})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`dependency_not_available`})}),(0,c.jsx)(t.td,{children:`error`})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`unused_dependencies`})}),(0,c.jsx)(t.td,{children:`warning`})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`formula_does_not_use_dependencies`})}),(0,c.jsx)(t.td,{children:`warning`})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`formula_runtime_error`})}),(0,c.jsx)(t.td,{children:`warning`})]})]})]}),`
841
+ `,(0,c.jsx)(t.h2,{id:`вопросы-и-ответы`,children:`Вопросы и ответы`}),`
842
+ `,(0,c.jsx)(t.h3,{id:`почему-неизвестная-formula-не-бросает-исключение`,children:`Почему неизвестная formula не бросает исключение?`}),`
843
+ `,(0,c.jsxs)(t.p,{children:[`Сохранённая конфигурация может ссылаться на удалённый id. Runtime представляет это как данные `,(0,c.jsx)(t.code,{children:`{ ok: false, reason: "formula_not_found" }`}),`, чтобы owner таблицы выбрал безопасный fallback.`]}),`
844
+ `,(0,c.jsxs)(t.h3,{id:`почему-formula-с-пустыми-keys-успешно-вернула-0`,children:[`Почему formula с пустыми keys успешно вернула `,(0,c.jsx)(t.code,{children:`0`}),`?`]}),`
845
+ `,(0,c.jsxs)(t.p,{children:[(0,c.jsx)(t.code,{children:`ctx.num`}),` для отсутствующего index возвращает `,(0,c.jsx)(t.code,{children:`0`}),`. Execution проверяет result, а не полноту dependency mapping. Запускайте validation до compile.`]}),`
846
+ `,(0,c.jsxs)(t.h3,{id:`почему-1-2345-стало-нулём`,children:[`Почему `,(0,c.jsx)(t.code,{children:`"1 234,5"`}),` стало нулём?`]}),`
847
+ `,(0,c.jsxs)(t.p,{children:[(0,c.jsx)(t.code,{children:`ctx.num`}),` использует встроенный `,(0,c.jsx)(t.code,{children:`Number`}),`, который не понимает такую локализованную запись. Читайте `,(0,c.jsx)(t.code,{children:`ctx.value`}),` и применяйте согласованный parser, если ваш transport действительно возвращает этот формат.`]}),`
848
+ `,(0,c.jsx)(t.h3,{id:`можно-ли-добавить-пользовательский-formula-text-из-бд`,children:`Можно ли добавить пользовательский formula text из БД?`}),`
849
+ `,(0,c.jsx)(t.p,{children:`Нет. Модуль намеренно исполняет только functions, заранее включённые разработчиком в registry. Для пользовательского expression language нужен отдельный безопасный parser, grammar, validation и execution policy.`}),`
850
+ `,(0,c.jsx)(t.h3,{id:`нужно-ли-компилировать-каждую-строку`,children:`Нужно ли компилировать каждую строку?`}),`
851
+ `,(0,c.jsx)(t.p,{children:`Нет. Компилируйте один раз для комбинации formula id + ordered keys и переиспользуйте executor для строк.`}),`
852
+ `,(0,c.jsx)(t.h3,{id:`можно-ли-менять-registry-после-компиляции`,children:`Можно ли менять registry после компиляции?`}),`
853
+ `,(0,c.jsx)(t.p,{children:`Можно технически, но существующие executors сохранят старую function, а новые получат новую. В приложении избегайте смешанного состояния: установите registry один раз при bootstrap.`}),`
854
+ `,(0,c.jsx)(t.h2,{id:`связанная-документация`,children:`Связанная документация`}),`
855
+ `,(0,c.jsxs)(t.ul,{children:[`
856
+ `,(0,c.jsx)(t.li,{children:(0,c.jsx)(t.a,{href:`../../README.md`,children:`Обзор пакета`})}),`
857
+ `,(0,c.jsx)(t.li,{children:(0,c.jsx)(t.a,{href:`../formatters/pipeline/README.mdx`,children:`Formatter pipeline`})}),`
858
+ `,(0,c.jsx)(t.li,{children:(0,c.jsx)(t.a,{href:`../formatters/rowBased/README.mdx`,children:`Row-based formatter`})}),`
859
+ `,(0,c.jsx)(t.li,{children:(0,c.jsx)(t.a,{href:`../formatters/number/README.mdx`,children:`Числовые formatter-ы`})}),`
860
+ `]})]})}function s(e={}){let{wrapper:t}={...n(),...e.components};return t?(0,c.jsx)(t,{...e,children:(0,c.jsx)(o,{...e})}):o(e)}var c;function l(){return(l=e((()=>{c=t(),r(),a()})))()}l();export{s as default};