@ryuzaki13/react-foundation-ui 1.4.2 → 1.4.4
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.
- package/dist/advanced-search/index.js +12 -11
- package/dist/advanced-search/index.js.map +1 -1
- package/dist/badge/index.js +1 -1
- package/dist/base-table/index.js +2 -2
- package/dist/button/index.js +1 -1
- package/dist/chunks/{CalendarView-KCkhCtK-.js → CalendarView-Z_XWk7aI.js} +8 -8
- package/dist/chunks/{CalendarView-KCkhCtK-.js.map → CalendarView-Z_XWk7aI.js.map} +1 -1
- package/dist/chunks/{ImageViewerRuntime-RN49by8Y.js → ImageViewerRuntime-BMs3BBkV.js} +4 -4
- package/dist/chunks/{ImageViewerRuntime-RN49by8Y.js.map → ImageViewerRuntime-BMs3BBkV.js.map} +1 -1
- package/dist/chunks/{TextEditorLexicalClient-CVTrglWP.js → TextEditorLexicalClient-CK8j3RA4.js} +16 -18
- package/dist/chunks/{TextEditorLexicalClient-CVTrglWP.js.map → TextEditorLexicalClient-CK8j3RA4.js.map} +1 -1
- package/dist/chunks/{badge-Cri0-kVK.js → badge-DwIUjH0a.js} +2 -2
- package/dist/chunks/{badge-Cri0-kVK.js.map → badge-DwIUjH0a.js.map} +1 -1
- package/dist/chunks/{base-table-D5IqsjQD.js → base-table-BFsVwXg3.js} +13 -12
- package/dist/chunks/{base-table-D5IqsjQD.js.map → base-table-BFsVwXg3.js.map} +1 -1
- package/dist/chunks/{button-CC0Jdx1j.js → button-BU2kRzwu.js} +2 -2
- package/dist/chunks/{button-CC0Jdx1j.js.map → button-BU2kRzwu.js.map} +1 -1
- package/dist/chunks/check-box-Dd3YFuxd.js.map +1 -1
- package/dist/chunks/{context-menu-DQeR3y7M.js → context-menu-C6RO7soI.js} +7 -2
- package/dist/chunks/{context-menu-DQeR3y7M.js.map → context-menu-C6RO7soI.js.map} +1 -1
- package/dist/chunks/{date-input-DBJisPRz.js → date-input-BzExUQnc.js} +5 -5
- package/dist/chunks/{date-input-DBJisPRz.js.map → date-input-BzExUQnc.js.map} +1 -1
- package/dist/chunks/{flex-DYZ0IbU6.js → flex-C7njxZ74.js} +10 -7
- package/dist/chunks/{flex-DYZ0IbU6.js.map → flex-C7njxZ74.js.map} +1 -1
- package/dist/chunks/floating-arrow-BE-z4QkE.js.map +1 -1
- package/dist/chunks/{input-BCJfUdK_.js → input-Bp6_Ucgr.js} +15 -15
- package/dist/chunks/{input-BCJfUdK_.js.map → input-Bp6_Ucgr.js.map} +1 -1
- package/dist/chunks/{input-files-Dcc5K-_1.js → input-files-D1JzSw_Y.js} +2 -2
- package/dist/chunks/{input-files-Dcc5K-_1.js.map → input-files-D1JzSw_Y.js.map} +1 -1
- package/dist/chunks/{input-search-B7HmrAM7.js → input-search-Bkhcinru.js} +2 -2
- package/dist/chunks/{input-search-B7HmrAM7.js.map → input-search-Bkhcinru.js.map} +1 -1
- package/dist/chunks/{misc-DIF5h9ba.js → misc-BYxxlJz6.js} +3 -3
- package/dist/chunks/{misc-DIF5h9ba.js.map → misc-BYxxlJz6.js.map} +1 -1
- package/dist/chunks/{modal-DXHX_sA-.js → modal-paexEF0j.js} +4 -5
- package/dist/chunks/{modal-DXHX_sA-.js.map → modal-paexEF0j.js.map} +1 -1
- package/dist/chunks/{multi-select-CWx12rgb.js → multi-select-COEkc8Qc.js} +4 -5
- package/dist/chunks/multi-select-COEkc8Qc.js.map +1 -0
- package/dist/chunks/{picker-BAQ9NeHe.js → picker-e6IsrMUG.js} +3 -3
- package/dist/chunks/{picker-BAQ9NeHe.js.map → picker-e6IsrMUG.js.map} +1 -1
- package/dist/chunks/{popover-xJJqy1v6.js → popover-CGU3MlsH.js} +14 -14
- package/dist/chunks/{popover-xJJqy1v6.js.map → popover-CGU3MlsH.js.map} +1 -1
- package/dist/chunks/radio-group-CM9Lg_nc.js.map +1 -1
- package/dist/chunks/{select-BPb-eL3O.js → select-BON0S9Dr.js} +115 -115
- package/dist/chunks/select-BON0S9Dr.js.map +1 -0
- package/dist/chunks/sortable-DcTIAbjD.js.map +1 -1
- package/dist/chunks/{table-xMAjqtcY.js → table-Dd5BcC0k.js} +3 -3
- package/dist/chunks/{table-xMAjqtcY.js.map → table-Dd5BcC0k.js.map} +1 -1
- package/dist/chunks/{table-column-interactions-BGd5Lwy9.js → table-column-interactions-DzEvVuXe.js} +8 -5
- package/dist/chunks/{table-column-interactions-BGd5Lwy9.js.map → table-column-interactions-DzEvVuXe.js.map} +1 -1
- package/dist/chunks/useODataSelectBase-CKe1AVMI.js.map +1 -1
- package/dist/chunks/wheel-picker-FS58cRsQ.js.map +1 -1
- package/dist/context-menu/index.js +1 -1
- package/dist/date-input/index.js +2 -2
- package/dist/date-time-input/index.js +4 -4
- package/dist/date-time-input/index.js.map +1 -1
- package/dist/detail/index.js.map +1 -1
- package/dist/dialog/index.js.map +1 -1
- package/dist/disclosure/index.js +1 -1
- package/dist/disclosure/index.js.map +1 -1
- package/dist/drop-zone/index.js +1 -1
- package/dist/drop-zone/index.js.map +1 -1
- package/dist/errors/index.js +1 -1
- package/dist/errors/index.js.map +1 -1
- package/dist/expandable-action-panel/index.js +2 -2
- package/dist/expandable-action-panel/index.js.map +1 -1
- package/dist/flex/index.js +1 -1
- package/dist/fullscreen-portal/index.js +3 -3
- package/dist/fullscreen-portal/index.js.map +1 -1
- package/dist/image/index.js +5 -5
- package/dist/image/index.js.map +1 -1
- package/dist/input/index.js +1 -1
- package/dist/input-date-time/index.js +1 -1
- package/dist/input-date-time/index.js.map +1 -1
- package/dist/input-file/index.js +1 -1
- package/dist/input-file/index.js.map +1 -1
- package/dist/input-files/index.js +1 -1
- package/dist/input-image/index.js +1 -1
- package/dist/input-image/index.js.map +1 -1
- package/dist/input-search/index.js +1 -1
- package/dist/layout-picker/index.js +3 -4
- package/dist/layout-picker/index.js.map +1 -1
- package/dist/layout-picker/ui/LayoutPicker.d.ts.map +1 -1
- package/dist/list/index.js +7 -7
- package/dist/list/index.js.map +1 -1
- package/dist/listbox/index.js.map +1 -1
- package/dist/misc/index.js +1 -1
- package/dist/modal/index.js +1 -1
- package/dist/multi-select/index.js +1 -1
- package/dist/multi-select/ui/MultiSelect.d.ts.map +1 -1
- package/dist/notifications/index.js +13 -11
- package/dist/notifications/index.js.map +1 -1
- package/dist/pages/index.js.map +1 -1
- package/dist/panel/index.js.map +1 -1
- package/dist/picker/index.js +1 -1
- package/dist/picker/types.d.ts +1 -1
- package/dist/picker/types.d.ts.map +1 -1
- package/dist/popover/index.js +1 -1
- package/dist/preset-range-date-input/index.js +2 -2
- package/dist/preset-range-date-input/index.js.map +1 -1
- package/dist/preset-select/index.js +1 -1
- package/dist/radio-button/index.js.map +1 -1
- package/dist/select/Select.d.ts.map +1 -1
- package/dist/select/index.js +1 -1
- package/dist/simple-table/index.js +1 -1
- package/dist/slider/index.js +27 -24
- package/dist/slider/index.js.map +1 -1
- package/dist/splitter/index.js.map +1 -1
- package/dist/state-select/index.js +12 -10
- package/dist/state-select/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/switch/index.js +1 -1
- package/dist/switch/index.js.map +1 -1
- package/dist/table/index.js +1 -1
- package/dist/table-column-interactions/index.js +1 -1
- package/dist/table-sorting/index.js +1 -1
- package/dist/table-sorting/index.js.map +1 -1
- package/dist/tabs/index.js +6 -6
- package/dist/tabs/index.js.map +1 -1
- package/dist/tag-input/index.js +1 -1
- package/dist/tag-input/index.js.map +1 -1
- package/dist/text/index.js +10 -8
- package/dist/text/index.js.map +1 -1
- package/dist/text-editor/index.js +2 -2
- package/dist/textarea/index.js +1 -1
- package/dist/textarea/index.js.map +1 -1
- package/dist/toggle/index.js.map +1 -1
- package/dist/toolbar/index.js +1 -2
- package/dist/toolbar/index.js.map +1 -1
- package/dist/tree/index.js.map +1 -1
- package/dist/tree-select/TreePickerBase.d.ts.map +1 -1
- package/dist/tree-select/index.js +134 -132
- package/dist/tree-select/index.js.map +1 -1
- package/dist/tree-table/index.js +2 -2
- package/dist/tree-table/index.js.map +1 -1
- package/package.json +52 -59
- package/storybook-static/assets/{Badge-SZ48u9qp.js → Badge-Bh73-APE.js} +11 -11
- package/storybook-static/assets/Badge.stories-gNFtCWnR.js +54 -0
- package/storybook-static/assets/{Button-CFCpYiPy.js → Button-O9QPAftp.js} +10 -10
- package/storybook-static/assets/Button-mjF9HSg0.js +12 -0
- package/storybook-static/assets/Button.stories-wkiE0c_a.js +75 -0
- package/storybook-static/assets/CalendarView-CqKlnF8k.js +1 -0
- package/storybook-static/assets/{DateInput-BfFTwd_P.css → CalendarView-DKvrkS40.css} +1 -1
- package/storybook-static/assets/{CheckBox-FoMSruZC.js → CheckBox-CB8fTQF0.js} +11 -11
- package/storybook-static/assets/CheckBox-Clpeg9q7.js +2 -0
- package/storybook-static/assets/CheckBox.module-BBzuj5He.js +1 -0
- package/storybook-static/assets/CheckBox.stories-pfWBxvOy.js +60 -0
- package/storybook-static/assets/Color-6AOWCN3U-CVvkiihj.js +1 -0
- package/storybook-static/assets/ContextMenu-Sv4wfyS3.js +1 -0
- package/storybook-static/assets/{ContextMenu-CU_1kOzV.js → ContextMenu-eGnlhRRu.js} +9 -9
- package/storybook-static/assets/ContextMenu.stories-CVw3hOvY.js +90 -0
- package/storybook-static/assets/DateInput-D8_Oleoy.js +1 -0
- package/storybook-static/assets/{DateInput-BeZ5esVE.js → DateInput-DQDplLib.js} +11 -11
- package/storybook-static/assets/DateInput-pmGiwdvw.css +1 -0
- package/storybook-static/assets/{DateInput.stories-Bkw2r8CD.js → DateInput.stories-BNpS4CND.js} +2 -2
- package/storybook-static/assets/DateRangePresetSelect-Bfx-d5qg.js +3 -0
- package/storybook-static/assets/{DateRangePresetSelect-C_mLvEoK.js → DateRangePresetSelect-DCBEf98i.js} +8 -8
- package/storybook-static/assets/DateRangePresetSelect.stories-PAV2jgQb.js +11 -0
- package/storybook-static/assets/{Detail-WzciiK9S.js → Detail-DvmdQCue.js} +11 -11
- package/storybook-static/assets/Detail.stories-CEm00aSN.js +44 -0
- package/storybook-static/assets/{Dialog-CwLsVxJY.js → Dialog-3I2Y7jD7.js} +9 -9
- package/storybook-static/assets/Dialog.stories-lcadmonM.js +31 -0
- package/storybook-static/assets/{Disclosure-BlRuGrk2.js → Disclosure-DUIQ37oh.js} +10 -10
- package/storybook-static/assets/Disclosure.stories-BeizaZWP.js +41 -0
- package/storybook-static/assets/DocsRenderer-JROSPFPF-DwPk6ai7.js +2 -0
- package/storybook-static/assets/{DropZone-Cr3nfCWA.js → DropZone-BGuCU5dq.js} +10 -10
- package/storybook-static/assets/DropZone.stories-B4J6OZ3T.js +44 -0
- package/storybook-static/assets/ExpandableActionPanel.stories-gCrqbhG6.js +20 -0
- package/storybook-static/assets/{Flex-C10912WS.js → Flex-CBwbh1yu.js} +18 -18
- package/storybook-static/assets/Flex.stories-cdk6vRZq.js +300 -0
- package/storybook-static/assets/FlexContainer-LmZIdhq2.js +1 -0
- package/storybook-static/assets/FlexItem-vkDYa5tA.js +3 -0
- package/storybook-static/assets/FloatingPopover-D4h-c24R.js +1 -0
- package/storybook-static/assets/FloatingPopover-DC84VrV3.css +1 -0
- package/storybook-static/assets/FormattedTableCell-CY3E21k8.css +1 -0
- package/storybook-static/assets/FormattedTableCell-Dh-kHTOC.js +18 -0
- package/storybook-static/assets/Grid-BCzygAqy.js +52 -0
- package/storybook-static/assets/{Grid-G88y3oB_.js → Grid-BkKqSMfk.js} +18 -18
- package/storybook-static/assets/{Grid.stories-BV7zL-6n.js → Grid.stories-828arrPi.js} +2 -2
- package/storybook-static/assets/{Grid-Bb0gH6CX.js → GridContainer-qDguE1HS.js} +2 -53
- package/storybook-static/assets/ImageCropper.stories-CrIWrKKR.js +115 -0
- package/storybook-static/assets/ImageRenderer-F3AaZx-K.js +2 -0
- package/storybook-static/assets/ImageRenderer.stories-l3PnRYxy.js +22 -0
- package/storybook-static/assets/ImageView.stories-C6uhkvCN.js +9 -0
- package/storybook-static/assets/{ImageViewer.stories-PlFXSB5n.js → ImageViewer.stories-BSPiv5lU.js} +5 -5
- package/storybook-static/assets/ImageViewerRuntime-BOpMGgz6.js +51 -0
- package/storybook-static/assets/Input-Co--DMHY.js +3 -0
- package/storybook-static/assets/{Input-pyUNDVtk.js → Input-D-ZrbHVw.js} +11 -11
- package/storybook-static/assets/Input.stories-vqPv6pLx.js +38 -0
- package/storybook-static/assets/{InputDateTime-CWk5KBwD.js → InputDateTime-DHBVbRii.js} +11 -11
- package/storybook-static/assets/InputDateTime.stories-BAvLMBuk.js +35 -0
- package/storybook-static/assets/{InputFile-BLQq7mY9.js → InputFile-B9TVOEZV.js} +10 -10
- package/storybook-static/assets/InputFile.stories-CypBLWFh.js +36 -0
- package/storybook-static/assets/{InputFiles-B6J4XBdP.js → InputFiles-CxZkOZFK.js} +10 -10
- package/storybook-static/assets/InputFiles.stories-BGwCp7OC.js +33 -0
- package/storybook-static/assets/InputFilesList-OEX4zGI3.js +1 -0
- package/storybook-static/assets/{InputImage--2PSB_E_.js → InputImage-31A6fxSf.js} +10 -10
- package/storybook-static/assets/InputImage.stories-CdpOudXI.js +51 -0
- package/storybook-static/assets/{LayoutPicker-RZDisgZ_.js → LayoutPicker-Dc55ovYM.js} +13 -13
- package/storybook-static/assets/LayoutPicker.stories-DXcn-WXQ.js +449 -0
- package/storybook-static/assets/{Listbox-xwfNjBpV.js → Listbox-DF8E6oMR.js} +10 -10
- package/storybook-static/assets/Listbox.stories-C98_9wX3.js +47 -0
- package/storybook-static/assets/{Modal-HJt_Y-a6.js → Modal-CXvDgktT.js} +12 -12
- package/storybook-static/assets/Modal.stories-DAC_QwN7.js +180 -0
- package/storybook-static/assets/MultiSelect-B-wX6JPo.js +2 -0
- package/storybook-static/assets/{MultiSelect-CvNsFdE4.js → MultiSelect-DN4foQlG.js} +11 -11
- package/storybook-static/assets/MultiSelect.stories-CgKNQmma.js +29 -0
- package/storybook-static/assets/MultiSelectToken-DDu5n78h.css +1 -0
- package/storybook-static/assets/MultiSelectToken-fjW8p4YG.js +1 -0
- package/storybook-static/assets/NoData-C7KqaHUh.css +1 -0
- package/storybook-static/assets/NoData-W7wK8oTW.js +1 -0
- package/storybook-static/assets/{NotificationsHost-DXCf3CQX.js → NotificationsHost-D1UoWmF8.js} +9 -9
- package/storybook-static/assets/NotificationsHost.stories-BWUuMmPl.js +25 -0
- package/storybook-static/assets/{ODataMultiSelect-CIJNiwGb.js → ODataMultiSelect-DE1V4el8.js} +15 -15
- package/storybook-static/assets/ODataMultiSelect.stories-Q1DUIL2W.js +73 -0
- package/storybook-static/assets/{ODataSelect-BDga9TUb.js → ODataSelect-CtoT2Wxx.js} +15 -15
- package/storybook-static/assets/ODataSelect.stories-DLi7Rwzk.js +73 -0
- package/storybook-static/assets/ODataTreeMultiSelect-DEZfgyPK.js +19 -0
- package/storybook-static/assets/ODataTreeMultiSelect.stories-H42q78xI.js +30 -0
- package/storybook-static/assets/ODataTreeSelect-BeylEiPN.js +17 -0
- package/storybook-static/assets/ODataTreeSelect.stories-MOILmtfY.js +24 -0
- package/storybook-static/assets/OneStepScroller-BSvYN6QP.js +5 -0
- package/storybook-static/assets/OneStepScroller-NRYd-egY.css +1 -0
- package/storybook-static/assets/{PeriodSelect-BJbjl62O.js → PeriodSelect-KQFGCxq6.js} +13 -13
- package/storybook-static/assets/PeriodSelect.stories-BIYx4_Yy.js +64 -0
- package/storybook-static/assets/PickerSelectionToolbar-Cvv8vTZm.js +2 -0
- package/storybook-static/assets/PickerTriggerActions-BBZmXagt.js +1 -0
- package/storybook-static/assets/{Popover-Dg2T0DoN.js → Popover-7YZIq8Fi.js} +11 -11
- package/storybook-static/assets/Popover-D6gSyjaW.js +2 -0
- package/storybook-static/assets/Popover-DGX7JNNK.css +1 -0
- package/storybook-static/assets/Popover.stories-DM69Ztws.js +69 -0
- package/storybook-static/assets/{PresetRangeDateInput-CNmTMNHF.js → PresetRangeDateInput-Ch6GapcJ.js} +8 -8
- package/storybook-static/assets/PresetRangeDateInput.stories-Cqd4eb0N.js +15 -0
- package/storybook-static/assets/PresetSelect-C8uIYhPJ.js +5 -0
- package/storybook-static/assets/{RadioButton-2rfUPkwC.js → RadioButton-BQjiyASl.js} +10 -10
- package/storybook-static/assets/RadioButton.stories-Cbho4i83.js +36 -0
- package/storybook-static/assets/RadioGroup-DNqu6WaC.js +1 -0
- package/storybook-static/assets/{RadioGroup-BduGGVKj.js → RadioGroup-vw4ObVj-.js} +10 -10
- package/storybook-static/assets/RadioGroup.stories-B-WQzZW_.js +42 -0
- package/storybook-static/assets/Scrollable-DrxMuH2M.js +1 -0
- package/storybook-static/assets/{Select-DnZ83aZs.js → Select-BxigZNtu.js} +13 -13
- package/storybook-static/assets/Select-X_O4M8Hi.js +12 -0
- package/storybook-static/assets/Select.stories-BpTrYJSr.js +46 -0
- package/storybook-static/assets/SelectOptionContent-RAmgWCOm.js +1 -0
- package/storybook-static/assets/{SerializableSelect-BiFhAxAJ.js → SerializableSelect-CA9wjk2m.js} +12 -12
- package/storybook-static/assets/SerializableSelect.stories-DXd4E-3U.js +46 -0
- package/storybook-static/assets/{SingleDateTimeInput-Bc-ifbML.js → SingleDateTimeInput-BeFLYUBF.js} +12 -12
- package/storybook-static/assets/SingleDateTimeInput.stories-B1aZ754N.js +78 -0
- package/storybook-static/assets/Slider-BYrHesOR.js +1 -0
- package/storybook-static/assets/{Slider-DfjBSsR3.js → Slider-BdWBkKp4.js} +15 -15
- package/storybook-static/assets/Slider.stories-CgmOhVBs.js +77 -0
- package/storybook-static/assets/{SliderInput-o9uCcVMP.js → SliderInput-QmF2VQWA.js} +16 -16
- package/storybook-static/assets/SliderInput.stories-MjSmhiOM.js +68 -0
- package/storybook-static/assets/{Sortable-B6Y9Q9Yn.js → Sortable-D5OTpesH.js} +13 -13
- package/storybook-static/assets/Sortable.stories-yz3c5EhY.js +141 -0
- package/storybook-static/assets/{Splitter-CfUVnAs7.js → Splitter-DVq6XBul.js} +11 -11
- package/storybook-static/assets/Splitter.stories-CopPw1_p.js +22 -0
- package/storybook-static/assets/{StateSelect-h0i4M4vO.js → StateSelect-ojwXeKmx.js} +10 -10
- package/storybook-static/assets/StateSelect.stories-D46m5HNn.js +47 -0
- package/storybook-static/assets/StringToggle.stories-ByYMmlXl.js +6 -0
- package/storybook-static/assets/{Switch-CPKaENqL.js → Switch-Dy4Pahkn.js} +10 -10
- package/storybook-static/assets/Switch.stories-EiAb5Z-D.js +26 -0
- package/storybook-static/assets/{Table-xV66crR1.js → Table-BO6Oa4JV.js} +22 -22
- package/storybook-static/assets/Table.stories--TpBKwmP.js +122 -0
- package/storybook-static/assets/{Tabs-v9YZeJoc.js → Tabs-7c93qVyH.js} +15 -15
- package/storybook-static/assets/Tabs.stories-DXZ0r2ix.js +58 -0
- package/storybook-static/assets/TagInput.stories-CoM8rXwa.js +18 -0
- package/storybook-static/assets/Text-BPlJUr3R.js +1 -0
- package/storybook-static/assets/{Textarea-CRThqX0z.js → Textarea-D3S4MkiX.js} +10 -10
- package/storybook-static/assets/Textarea.stories-47k8uHdB.js +27 -0
- package/storybook-static/assets/TimePanel-C2iZ9Qr6.js +1 -0
- package/storybook-static/assets/TimePanel.stories-JTjIv6z1.js +25 -0
- package/storybook-static/assets/{Toggle-CzopviU2.js → Toggle-CHmajZE5.js} +10 -10
- package/storybook-static/assets/Toggle-OlKw8qaK.js +1 -0
- package/storybook-static/assets/Toggle.stories-k4Z8qQVs.js +30 -0
- package/storybook-static/assets/TreeMultiSelect-BC_n1Wb-.js +1 -0
- package/storybook-static/assets/TreeMultiSelect-dOg0l7rk.js +19 -0
- package/storybook-static/assets/TreeMultiSelect.stories-CAzZRxn5.js +35 -0
- package/storybook-static/assets/TreePickerBase-ycYQYQgi.js +22 -0
- package/storybook-static/assets/TreeSelect-BrNyI_Qx.js +16 -0
- package/storybook-static/assets/TreeSelect-CDecTnag.js +1 -0
- package/storybook-static/assets/TreeSelect.stories-BUOw2Rwn.js +18 -0
- package/storybook-static/assets/{TreeTable-DbzoCcR5.js → TreeTable-BXw7lFBk.js} +22 -22
- package/storybook-static/assets/TreeTable.stories-z40pruPV.js +83 -0
- package/storybook-static/assets/WithTooltip-7X4HQR7L-Cakt_JaX.js +9 -0
- package/storybook-static/assets/array-BBSjoTRy-CIRmlF93.js +1 -0
- package/storybook-static/assets/{async-D27PcxoG.js → async-BLDV04P4.js} +3 -3
- package/storybook-static/assets/axe-Bq-2xuso.js +20 -0
- package/storybook-static/assets/blocks-BiaKjftm.js +48 -0
- package/storybook-static/assets/browserAndReact-DX4H5rjQ.js +105 -0
- package/storybook-static/assets/check-fB4gCKB_.js +1 -0
- package/storybook-static/assets/chevron-down-B9GH0QvB.js +1 -0
- package/storybook-static/assets/chevron-left-DjbyJeHO.js +1 -0
- package/storybook-static/assets/chevron-right-D29uf09I.js +1 -0
- package/storybook-static/assets/chunk-242VQQM5-BMWWiybC.js +1 -0
- package/storybook-static/assets/chunk-DRQKCCAG-CqE-Zrl9.js +1 -0
- package/storybook-static/assets/chunk-IMSF75WX-yvVUwIQZ.js +6 -0
- package/storybook-static/assets/chunk-KJHJLCBK-D-yQfkOi.js +1 -0
- package/storybook-static/assets/chunk-QQBDHPVZ-B98qboss.js +1 -0
- package/storybook-static/assets/chunk-W22LQPXL-CGkHFiZ0.js +18 -0
- package/storybook-static/assets/circle-alert-Dmd7-WNp.js +1 -0
- package/storybook-static/assets/circle-check-VtVMsaJJ.js +1 -0
- package/storybook-static/assets/components-CsfQDbHv.js +241 -0
- package/storybook-static/assets/contextMenu-CzdfaUsd.js +2 -0
- package/storybook-static/assets/date-segments-D3HouZ37.js +1 -0
- package/storybook-static/assets/dom-B3G_GtJw.js +1 -0
- package/storybook-static/assets/download-CyVhTbv6.js +1 -0
- package/storybook-static/assets/error-BZrNlEUO.js +1 -0
- package/storybook-static/assets/file-vPGnhPr-.js +1 -0
- package/storybook-static/assets/filesAndExcel-DlUnL-Uu.js +122 -0
- package/storybook-static/assets/floating-ui.react-DZ8IyUV4.js +1 -0
- package/storybook-static/assets/formatter-L2YTDE3Q-x0raBH34.js +1 -0
- package/storybook-static/assets/formatters--mhLir82-v41eaI4a.js +1 -0
- package/storybook-static/assets/formatters-BTz64vfu.js +291 -0
- package/storybook-static/assets/formatters-runtime-DVi3RdYb.js +384 -0
- package/storybook-static/assets/foundationLib-CFj4J-Pc.js +82 -0
- package/storybook-static/assets/hooks-Ch5aYb7R.js +5 -0
- package/storybook-static/assets/iframe-Cr7AcW_R.js +1 -0
- package/storybook-static/assets/iframe-DaN-XFub.js +1151 -0
- package/storybook-static/assets/info-Cirk1RKZ.js +1 -0
- package/storybook-static/assets/{matchers-JIUQ3HVY-BPS-eazD.js → matchers-JIUQ3HVY-DvR2XErZ.js} +3 -3
- package/storybook-static/assets/media-BycWpjAl.js +1 -0
- package/storybook-static/assets/odata-BtfB5Aje.js +1 -0
- package/storybook-static/assets/odata-service-DnPlNGpU-Bpd4Zh9L.js +3 -0
- package/storybook-static/assets/odataAndTables-TEZyQ-TZ.js +126 -0
- package/storybook-static/assets/{odataFetchFn-BVgXXKgx.js → odataFetchFn-DEKVPDzV.js} +3 -3
- package/storybook-static/assets/odataStoryFixtures-CDDaJZKW.js +25 -0
- package/storybook-static/assets/{persisted-D8qUQbts.js → persisted-BzLLmgUK.js} +3 -3
- package/storybook-static/assets/preload-helper-BHmFeTtP.js +1 -0
- package/storybook-static/assets/pureUtilities-Dw249t3R.js +69 -0
- package/storybook-static/assets/react-18-CgkwBzTo.js +9 -0
- package/storybook-static/assets/react-C21x__mS.js +1 -0
- package/storybook-static/assets/react-CvkUhHUq.js +1 -0
- package/storybook-static/assets/react-KzpmXJc9.js +9 -0
- package/storybook-static/assets/react-dom-2o2phaJG.js +1 -0
- package/storybook-static/assets/react-qN2cStNd.js +1 -0
- package/storybook-static/assets/refresh-cw-BN3JCsXv.js +1 -0
- package/storybook-static/assets/rolldown-runtime-C0FnF6B9.js +1 -0
- package/storybook-static/assets/runtimeAndState-CCVgv3ck.js +117 -0
- package/storybook-static/assets/settings-2-jtcbbWm5.js +1 -0
- package/storybook-static/assets/sortable-dNWaObUX.js +1 -0
- package/storybook-static/assets/syntaxhighlighter-T5IQBZDB-hYwVxXYm.js +6 -0
- package/storybook-static/assets/theming-mTWhffkp.js +39 -0
- package/storybook-static/assets/trash-2-DrVfT0z5.js +1 -0
- package/storybook-static/assets/treeStoryFixtures-Ci7STpiz.js +1 -0
- package/storybook-static/assets/triangle-alert-B1Q28Bq9.js +1 -0
- package/storybook-static/assets/ui.module-DoMIk8Oc.js +1 -0
- package/storybook-static/assets/uiClasses-CO3Cdv1E.js +1 -0
- package/storybook-static/assets/useFlexClasses-Gn9spXEB.js +1 -0
- package/storybook-static/assets/useODataSelectBase-DlbeGYUP.js +1 -0
- package/storybook-static/assets/useODataTreeData-CvsoLfiG.js +1 -0
- package/storybook-static/assets/usePickerDefaultFilter-DdxyE_i8.js +1 -0
- package/storybook-static/assets/usePickerQuery-6rDaPaB0.js +1 -0
- package/storybook-static/assets/usePickerTriggerController-BHBjSLtn.js +1 -0
- package/storybook-static/assets/utils-DUM89eIj.js +1 -0
- package/storybook-static/assets/x-Dh43gJN9.js +1 -0
- package/storybook-static/iframe.html +8 -3
- package/storybook-static/index.html +6 -0
- package/storybook-static/index.json +1 -1
- package/storybook-static/project.json +1 -1
- package/storybook-static/sb-addons/a11y-3/manager-bundle.js +3 -3
- package/storybook-static/sb-addons/chromatic-com-storybook-1/manager-bundle.js +17 -17
- package/storybook-static/sb-addons/docs-2/manager-bundle.js +16 -1
- package/storybook-static/sb-addons/storybook-core-server-presets-0/common-manager-bundle.js +85 -83
- package/storybook-static/sb-addons/vitest-4/manager-bundle.js +1 -1
- package/storybook-static/sb-manager/globals-runtime.js +9939 -7695
- package/storybook-static/sb-manager/runtime.js +16128 -15326
- package/storybook-static/vite-inject-mocker-entry.js +2 -2
- package/dist/chunks/multi-select-CWx12rgb.js.map +0 -1
- package/dist/chunks/select-BPb-eL3O.js.map +0 -1
- package/storybook-static/assets/Badge.stories-CzsgAfG9.js +0 -51
- package/storybook-static/assets/Button-MoWVKehO.js +0 -12
- package/storybook-static/assets/Button.stories-wwep4c2p.js +0 -75
- package/storybook-static/assets/CheckBox-DHvne_6w.js +0 -2
- package/storybook-static/assets/CheckBox.module-ezWPE2pa.js +0 -1
- package/storybook-static/assets/CheckBox.stories-C14Axs5p.js +0 -60
- package/storybook-static/assets/Color-KMSTOMOX-CmMBFN4-.js +0 -1
- package/storybook-static/assets/ContextMenu.stories-Dr-tkpqd.js +0 -90
- package/storybook-static/assets/DateInput-erobPRG_.js +0 -1
- package/storybook-static/assets/DateRangePresetSelect-Cg90Kc_w.js +0 -3
- package/storybook-static/assets/DateRangePresetSelect.stories-BVap0joC.js +0 -11
- package/storybook-static/assets/Detail.stories-CLdtvJ7q.js +0 -44
- package/storybook-static/assets/Dialog.stories-Dx0jZO19.js +0 -31
- package/storybook-static/assets/Disclosure.stories-DhUdeDK6.js +0 -41
- package/storybook-static/assets/DocsRenderer-JROSPFPF-Dd1n83Uq.js +0 -2
- package/storybook-static/assets/DropZone.stories-6yYrwQOe.js +0 -44
- package/storybook-static/assets/DropdownMenu-D_2LfViU.js +0 -1
- package/storybook-static/assets/ExpandableActionPanel.stories-DVOFSOlm.js +0 -20
- package/storybook-static/assets/Flex-V-qg6Ejw.js +0 -3
- package/storybook-static/assets/Flex.stories-BZv94LD8.js +0 -300
- package/storybook-static/assets/ImageCropper.stories-MLFZyJxZ.js +0 -115
- package/storybook-static/assets/ImageRenderer-DHhD7mUz.js +0 -2
- package/storybook-static/assets/ImageRenderer.stories-ChcPymk2.js +0 -22
- package/storybook-static/assets/ImageView.stories-DszVNgC8.js +0 -9
- package/storybook-static/assets/ImageViewerRuntime-D8wFAKx5.js +0 -51
- package/storybook-static/assets/Input-BGdz8TmT.js +0 -3
- package/storybook-static/assets/Input.stories-Ban0Gnck.js +0 -38
- package/storybook-static/assets/InputDateTime.stories-DgKVmf54.js +0 -35
- package/storybook-static/assets/InputFile.stories-VnRv_q2r.js +0 -36
- package/storybook-static/assets/InputFiles-Dn9afnyd.js +0 -1
- package/storybook-static/assets/InputFiles.stories-CLVn5Xfq.js +0 -33
- package/storybook-static/assets/InputImage.stories-D__QcSho.js +0 -51
- package/storybook-static/assets/LayoutPicker.stories-BCnR-zBu.js +0 -449
- package/storybook-static/assets/Listbox.stories-B0HctqVp.js +0 -47
- package/storybook-static/assets/Modal.stories-BE-VpK-a.js +0 -180
- package/storybook-static/assets/MultiSelect-BoIwmje6.css +0 -1
- package/storybook-static/assets/MultiSelect-CaCNRNIe.js +0 -2
- package/storybook-static/assets/MultiSelect.stories-CNkbVGsb.js +0 -29
- package/storybook-static/assets/NotificationsHost.stories-BgqvZzT3.js +0 -25
- package/storybook-static/assets/ODataMultiSelect-CMyI4yYs.js +0 -1
- package/storybook-static/assets/ODataMultiSelect.stories-DTGCC6np.js +0 -73
- package/storybook-static/assets/ODataSelect-CGplYBh_.js +0 -1
- package/storybook-static/assets/ODataSelect.stories-CsxqRAvn.js +0 -73
- package/storybook-static/assets/ODataTreeMultiSelect-4ZiAtFZk.js +0 -19
- package/storybook-static/assets/ODataTreeMultiSelect.stories-B29Od8BL.js +0 -30
- package/storybook-static/assets/ODataTreeSelect-yZy7MBsZ.js +0 -17
- package/storybook-static/assets/ODataTreeSelect.stories-H7eaj1Sz.js +0 -24
- package/storybook-static/assets/PeriodSelect.stories-6CEzS2_H.js +0 -64
- package/storybook-static/assets/Popover.stories-BNgWOHlJ.js +0 -69
- package/storybook-static/assets/PresetRangeDateInput.stories-6UPVDF62.js +0 -15
- package/storybook-static/assets/RadioButton.stories-DbdFfJqO.js +0 -36
- package/storybook-static/assets/RadioGroup-BA21indC.js +0 -1
- package/storybook-static/assets/RadioGroup.stories-Ce6x0WUN.js +0 -42
- package/storybook-static/assets/Select-DyO25wSA.js +0 -12
- package/storybook-static/assets/Select.stories-CQ8f9fY9.js +0 -46
- package/storybook-static/assets/SelectOptionContent-fC4HFG5Q.js +0 -1
- package/storybook-static/assets/SerializableSelect-ki4BThj7.js +0 -4
- package/storybook-static/assets/SerializableSelect.stories-BzXBkWPI.js +0 -43
- package/storybook-static/assets/SingleDateTimeInput.stories-CI2yrD-f.js +0 -78
- package/storybook-static/assets/Slider.stories-D3O3_tqE.js +0 -77
- package/storybook-static/assets/SliderInput.stories-D1puleZB.js +0 -67
- package/storybook-static/assets/Sortable.stories-BoaL4W6r.js +0 -141
- package/storybook-static/assets/Splitter.stories-DJpFzZVJ.js +0 -22
- package/storybook-static/assets/StateSelect.stories-Ch2Gzzmd.js +0 -47
- package/storybook-static/assets/StringToggle.stories-B8qIG0M3.js +0 -6
- package/storybook-static/assets/Switch.stories-BysIhUHa.js +0 -26
- package/storybook-static/assets/Table.stories-CBpgmq7b.js +0 -122
- package/storybook-static/assets/Tabs.stories-BPYZuvzR.js +0 -58
- package/storybook-static/assets/TagInput.stories-BwOEnVpz.js +0 -18
- package/storybook-static/assets/Textarea.stories-BSJGz7JF.js +0 -27
- package/storybook-static/assets/TimePanel-ClMfq_py.js +0 -1
- package/storybook-static/assets/TimePanel.stories-_FqWdmta.js +0 -25
- package/storybook-static/assets/Toggle-BFhzeK2e.js +0 -1
- package/storybook-static/assets/Toggle.stories-Dw5UkD_b.js +0 -30
- package/storybook-static/assets/TreeMultiSelect-CerqHY2K.js +0 -19
- package/storybook-static/assets/TreeMultiSelect-Dw7FI3ic.js +0 -1
- package/storybook-static/assets/TreeMultiSelect.stories-BTQKFbeP.js +0 -35
- package/storybook-static/assets/TreePickerBase-rJISGJBT.js +0 -22
- package/storybook-static/assets/TreeSelect-CQ1vj_c9.js +0 -16
- package/storybook-static/assets/TreeSelect-Cp_lX0-B.js +0 -1
- package/storybook-static/assets/TreeSelect.stories-D6Q02Phx.js +0 -18
- package/storybook-static/assets/TreeTable.stories-YfyhkqH9.js +0 -83
- package/storybook-static/assets/WithTooltip-7X4HQR7L-BSQyvCOM.js +0 -9
- package/storybook-static/assets/axe-GLfyhAYL.js +0 -20
- package/storybook-static/assets/base-table-BNO0lnTL.css +0 -1
- package/storybook-static/assets/base-table-Dy3fEhQe.js +0 -18
- package/storybook-static/assets/blocks-ixiC6_NZ.js +0 -285
- package/storybook-static/assets/button-DZpTIXz2.js +0 -1
- package/storybook-static/assets/check-box-DByHwJGx.js +0 -1
- package/storybook-static/assets/chunk-242VQQM5-Dtm7LRbQ.js +0 -1
- package/storybook-static/assets/chunk-3LY4VQVK-BohfESrT.js +0 -6
- package/storybook-static/assets/chunk-LITCR56V-XaMGADKk.js +0 -18
- package/storybook-static/assets/contextMenu-BbMrBF3b.js +0 -2
- package/storybook-static/assets/date-7kR6zFX5.js +0 -461
- package/storybook-static/assets/date-segments-CzU9k5bl.js +0 -1
- package/storybook-static/assets/error-BRUjWXbJ.js +0 -1
- package/storybook-static/assets/file-CI_sonB1.js +0 -291
- package/storybook-static/assets/file-hArYcyES.js +0 -1
- package/storybook-static/assets/flex-C--89Z3g.js +0 -1
- package/storybook-static/assets/floating-ui.react-DLXcGGFR.js +0 -1
- package/storybook-static/assets/formatter-L2YTDE3Q-DgyzUf7M.js +0 -1
- package/storybook-static/assets/formatters-BtIOYENB.js +0 -3
- package/storybook-static/assets/formulas-DRh9I2eS.js +0 -2
- package/storybook-static/assets/grid-DLxeTZJe.js +0 -1
- package/storybook-static/assets/hooks-DWeJq8G1.js +0 -5
- package/storybook-static/assets/iframe-BJGIOdSH.js +0 -1119
- package/storybook-static/assets/input-DXi75xv1.js +0 -1
- package/storybook-static/assets/mdx-react-shim-CmoAsjhK.js +0 -1
- package/storybook-static/assets/media-DWFaNgLM.js +0 -1
- package/storybook-static/assets/misc-BElIqBdV.css +0 -1
- package/storybook-static/assets/misc-DNZTbWc6.js +0 -5
- package/storybook-static/assets/notifications-DjtgzFqT.js +0 -1
- package/storybook-static/assets/number-Xkw1yPJo.js +0 -2
- package/storybook-static/assets/odata-C4Liwkjx.js +0 -1
- package/storybook-static/assets/odata-service-C2oJ-ZmZ.js +0 -1
- package/storybook-static/assets/odataStoryFixtures-eEGvvtmw.js +0 -25
- package/storybook-static/assets/picker-DsP4xCcJ.js +0 -2
- package/storybook-static/assets/popover-BiQHI7Wi.css +0 -1
- package/storybook-static/assets/popover-CuFTypCp.js +0 -2
- package/storybook-static/assets/preload-helper-B45gAKPr.js +0 -1
- package/storybook-static/assets/preset-select-SPNHA-mp.js +0 -5
- package/storybook-static/assets/pwa-B7uYfAPd.js +0 -640
- package/storybook-static/assets/queryClient-CA0puYc0.js +0 -567
- package/storybook-static/assets/react-18-CaNSmcD-.js +0 -9
- package/storybook-static/assets/react-3qMIUlAf.js +0 -9
- package/storybook-static/assets/react-dom-BC7xZNHy.js +0 -1
- package/storybook-static/assets/select-sUla5-3b.js +0 -1
- package/storybook-static/assets/slider--Yp_sa_W.js +0 -2
- package/storybook-static/assets/sortable-jALaQqYE.js +0 -1
- package/storybook-static/assets/syntaxhighlighter-RTCFPKCB-u_WDwfDn.js +0 -6
- package/storybook-static/assets/text-D5xgciF8.js +0 -4
- package/storybook-static/assets/theming-oB64gsjY.js +0 -39
- package/storybook-static/assets/treeStoryFixtures-Y_nnjz0_.js +0 -1
- package/storybook-static/assets/ui-DWDaBPQx.js +0 -1
- package/storybook-static/assets/ui.module-wFHXkJzp.js +0 -1
- package/storybook-static/assets/uiClasses-CaHp0EWd.js +0 -1
- package/storybook-static/assets/useODataSelectBase-DjlPxmxr.js +0 -1
- package/storybook-static/assets/useODataTreeData-1W6cbuec.js +0 -1
- package/storybook-static/assets/utils-DzbSigQl.js +0 -1
- package/storybook-static/assets/valueState-GnkKWBTr.js +0 -277
- /package/storybook-static/assets/{DropdownMenu-BgzIzwzM.css → ContextMenu-BgzIzwzM.css} +0 -0
- /package/storybook-static/assets/{Grid-K9R_IHaw.css → GridContainer-K9R_IHaw.css} +0 -0
- /package/storybook-static/assets/{InputFiles-ByK52qUe.css → InputFilesList-ByK52qUe.css} +0 -0
- /package/storybook-static/assets/{slider-DMDFRH6B.css → Slider-DMDFRH6B.css} +0 -0
- /package/storybook-static/assets/{Flex-IXK2se1Y.css → useFlexClasses-IXK2se1Y.css} +0 -0
- /package/storybook-static/assets/{picker-DzBkX15M.css → usePickerTriggerController-DzBkX15M.css} +0 -0
|
@@ -1,567 +0,0 @@
|
|
|
1
|
-
import{i as e}from"./preload-helper-B45gAKPr.js";import{t}from"./iframe-BJGIOdSH.js";import{E as n,c as r,l as i,m as a}from"./blocks-ixiC6_NZ.js";import{t as o}from"./mdx-react-shim-CmoAsjhK.js";var s,c=e((()=>{s=`# Query Client
|
|
2
|
-
|
|
3
|
-
Модуль \`src/shared/lib/query-client\` содержит общую инфраструктуру TanStack Query:
|
|
4
|
-
|
|
5
|
-
- создание singleton \`QueryClient\`;
|
|
6
|
-
- opt-in сохранение справочных query в IndexedDB;
|
|
7
|
-
- синхронизацию кэша и прикладных cache-событий между вкладками;
|
|
8
|
-
- безопасный сброс auth-зависимых query при смене серверной сессии.
|
|
9
|
-
|
|
10
|
-
Полная схема кеширования OData metadata, version-check и справочников описана в [docs/odata-reference-cache.md](/docs/odata-reference-cache.md).
|
|
11
|
-
|
|
12
|
-
## IndexedDB persistence для справочников
|
|
13
|
-
|
|
14
|
-
### Назначение
|
|
15
|
-
|
|
16
|
-
Модуль [persistence.ts](/src/shared/lib/query-client/persistence.ts) сохраняет выбранные данные TanStack Query в IndexedDB.
|
|
17
|
-
|
|
18
|
-
Задача этого слоя — переживать перезагрузку страницы и повторный вход в SPA для тяжёлых справочных данных, не используя \`localStorage\`.
|
|
19
|
-
|
|
20
|
-
Почему не \`localStorage\`:
|
|
21
|
-
|
|
22
|
-
- он синхронный и может блокировать UI на больших payload;
|
|
23
|
-
- браузерные лимиты обычно заметно ниже;
|
|
24
|
-
- объёмы справочников в ARM могут доходить до 100-200 МБ;
|
|
25
|
-
- IndexedDB лучше подходит для больших асинхронных клиентских хранилищ.
|
|
26
|
-
|
|
27
|
-
Почему не Service Worker:
|
|
28
|
-
|
|
29
|
-
- SW runtime cache работает на уровне HTTP-запросов;
|
|
30
|
-
- React Query persistence работает на уровне уже нормализованных query-данных;
|
|
31
|
-
- текущая реализация не зависит от регистрации SW и работает в обычном SPA-входе.
|
|
32
|
-
|
|
33
|
-
### Как это подключено
|
|
34
|
-
|
|
35
|
-
Persistence подключается в [queryClient.ts](/src/shared/lib/query-client/queryClient.ts) при создании \`QueryClient\`:
|
|
36
|
-
|
|
37
|
-
\`\`\`ts
|
|
38
|
-
export function createQueryClient({ onQueryError, onMutationError }: QueryBroadcastOptions) {
|
|
39
|
-
const queryPersister = createReactQueryPersister();
|
|
40
|
-
|
|
41
|
-
return new QueryClient({
|
|
42
|
-
defaultOptions: {
|
|
43
|
-
queries: {
|
|
44
|
-
staleTime: 10 * 60 * 1000,
|
|
45
|
-
gcTime: 30 * 60 * 1000,
|
|
46
|
-
...(queryPersister ? { persister: queryPersister.persisterFn } : {})
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
\`\`\`
|
|
52
|
-
|
|
53
|
-
Если код выполняется не в браузере или \`indexedDB\` недоступен, \`createReactQueryPersister()\` возвращает \`undefined\`, а \`QueryClient\` создаётся без persistence.
|
|
54
|
-
|
|
55
|
-
### Главный принцип: opt-in
|
|
56
|
-
|
|
57
|
-
Сохраняются не все query, а только те, которые явно помечены:
|
|
58
|
-
|
|
59
|
-
\`\`\`ts
|
|
60
|
-
meta: persistedQueryMeta;
|
|
61
|
-
\`\`\`
|
|
62
|
-
|
|
63
|
-
\`persistedQueryMeta\` экспортируется из \`@/shared/lib\` и имеет форму:
|
|
64
|
-
|
|
65
|
-
\`\`\`ts
|
|
66
|
-
export const persistedQueryMeta = { persist: true } as const;
|
|
67
|
-
\`\`\`
|
|
68
|
-
|
|
69
|
-
Фильтр persistence проверяет это так:
|
|
70
|
-
|
|
71
|
-
\`\`\`ts
|
|
72
|
-
export function shouldPersistQuery(query: Pick<Query, "meta">) {
|
|
73
|
-
return query.meta?.persist === true && query.meta.sessionScoped !== true;
|
|
74
|
-
}
|
|
75
|
-
\`\`\`
|
|
76
|
-
|
|
77
|
-
Это важно для безопасности и управляемости объёма:
|
|
78
|
-
|
|
79
|
-
- transient UI-запросы не попадают в IndexedDB;
|
|
80
|
-
- пользовательские или чувствительные данные не начинают сохраняться случайно;
|
|
81
|
-
- размер persistent cache растёт только там, где это осознанно включили.
|
|
82
|
-
|
|
83
|
-
## Session-scoped query
|
|
84
|
-
|
|
85
|
-
Если содержимое query или право на её чтение зависит от текущей серверной
|
|
86
|
-
сессии, query нужно пометить отдельно:
|
|
87
|
-
|
|
88
|
-
\`\`\`ts
|
|
89
|
-
meta: sessionScopedQueryMeta;
|
|
90
|
-
\`\`\`
|
|
91
|
-
|
|
92
|
-
После входа, выхода, обновления сессии или потери авторизации приложение вызывает:
|
|
93
|
-
|
|
94
|
-
\`\`\`ts
|
|
95
|
-
await resetSessionScopedQueries(queryClient);
|
|
96
|
-
\`\`\`
|
|
97
|
-
|
|
98
|
-
Механизм отменяет незавершённые запросы прежней сессии, очищает только query с
|
|
99
|
-
\`meta.sessionScoped = true\` и повторно запрашивает их активные экземпляры.
|
|
100
|
-
Публичный кеш при этом не затрагивается.
|
|
101
|
-
|
|
102
|
-
Для синхронизации нескольких вкладок приложение один раз подключает служебный
|
|
103
|
-
канал через \`installSessionScopedQueryReset\`. Канал передаёт только команду
|
|
104
|
-
сброса, но не данные query, auth payload или токены. Это принципиально отличает
|
|
105
|
-
его от полной межвкладочной синхронизации Query cache.
|
|
106
|
-
|
|
107
|
-
\`persistedQueryMeta\` и \`sessionScopedQueryMeta\` нельзя совмещать. Даже если оба
|
|
108
|
-
признака ошибочно указаны вручную, фильтр persistence не сохранит session-scoped
|
|
109
|
-
query в IndexedDB.
|
|
110
|
-
|
|
111
|
-
### Что сохраняется сейчас
|
|
112
|
-
|
|
113
|
-
На текущем этапе persistence включён только для справочников:
|
|
114
|
-
|
|
115
|
-
- OData metadata в [useODataMetadataQuery.ts](/src/shared/api/odata/useODataMetadataQuery.ts);
|
|
116
|
-
- OData metadata-version в [metadataVersionCheck.ts](/src/shared/api/odata/metadataVersionCheck.ts);
|
|
117
|
-
- OData collection-updates в [useODataCollectionUpdatesQuery.ts](/src/shared/api/odata/useODataCollectionUpdatesQuery.ts);
|
|
118
|
-
- OData collection в [useODataCollectionQuery.ts](/src/shared/api/odata/useODataCollectionQuery.ts).
|
|
119
|
-
|
|
120
|
-
Пример metadata query:
|
|
121
|
-
|
|
122
|
-
\`\`\`ts
|
|
123
|
-
export const odataMetadataQueryOptions = (options: ODataMetadataOptions) =>
|
|
124
|
-
queryOptions({
|
|
125
|
-
queryKey: [...odataBaseQueryKey, "metadata", options],
|
|
126
|
-
queryFn: fetchMetadata(options),
|
|
127
|
-
meta: persistedQueryMeta,
|
|
128
|
-
staleTime: Infinity,
|
|
129
|
-
gcTime: Infinity
|
|
130
|
-
});
|
|
131
|
-
\`\`\`
|
|
132
|
-
|
|
133
|
-
Пример collection query:
|
|
134
|
-
|
|
135
|
-
\`\`\`ts
|
|
136
|
-
return useQuery({
|
|
137
|
-
queryKey,
|
|
138
|
-
queryFn: fetchCollection,
|
|
139
|
-
enabled: Boolean(!isLoading && metadata && service && target),
|
|
140
|
-
meta: persistedQueryMeta,
|
|
141
|
-
staleTime: 1000 * 60 * 60 * 2,
|
|
142
|
-
gcTime: 1000 * 60 * 60
|
|
143
|
-
});
|
|
144
|
-
\`\`\`
|
|
145
|
-
|
|
146
|
-
### Как устроено хранилище
|
|
147
|
-
|
|
148
|
-
\`createIndexedDbQueryStorage()\` создаёт storage-адаптер под интерфейс \`AsyncStorage\` из \`@tanstack/query-persist-client-core\`.
|
|
149
|
-
|
|
150
|
-
Он реализует методы:
|
|
151
|
-
|
|
152
|
-
\`\`\`ts
|
|
153
|
-
type QueryStorage<T> = {
|
|
154
|
-
getItem: (key: string) => Promise<T | undefined | null>;
|
|
155
|
-
setItem: (key: string, value: T) => Promise<unknown>;
|
|
156
|
-
removeItem: (key: string) => Promise<void>;
|
|
157
|
-
entries: () => Promise<Array<[key: string, value: T]>>;
|
|
158
|
-
};
|
|
159
|
-
\`\`\`
|
|
160
|
-
|
|
161
|
-
Физически данные лежат в:
|
|
162
|
-
|
|
163
|
-
- database: текущий system/client контекст, в dev-режиме \`dev\`;
|
|
164
|
-
- object store: \`queries\`.
|
|
165
|
-
|
|
166
|
-
\`entries()\` нужен не для обычного lazy restore конкретной query, а для служебных сценариев TanStack persister: garbage collection, массовое восстановление и удаление query.
|
|
167
|
-
|
|
168
|
-
### Как формируются ключи IndexedDB
|
|
169
|
-
|
|
170
|
-
TanStack persister сохраняет каждую query отдельной записью.
|
|
171
|
-
|
|
172
|
-
Ключ записи строится из:
|
|
173
|
-
|
|
174
|
-
- \`prefix\`;
|
|
175
|
-
- \`queryHash\`.
|
|
176
|
-
|
|
177
|
-
В ARM prefix учитывает system/client контекст:
|
|
178
|
-
|
|
179
|
-
\`\`\`ts
|
|
180
|
-
<system>:cache
|
|
181
|
-
\`\`\`
|
|
182
|
-
|
|
183
|
-
Это не смешивает кэш разных окружений, например разных SAP-систем и клиентов.
|
|
184
|
-
|
|
185
|
-
Пример итогового ключа в IndexedDB:
|
|
186
|
-
|
|
187
|
-
\`\`\`text
|
|
188
|
-
<system>:cache-["odata","metadata",{"service":"TEXT_APP_SRV"}]
|
|
189
|
-
\`\`\`
|
|
190
|
-
|
|
191
|
-
Фактический \`queryHash\` формирует TanStack Query, поэтому руками такие ключи создавать не нужно.
|
|
192
|
-
|
|
193
|
-
### Что лежит в записи
|
|
194
|
-
|
|
195
|
-
Каждая запись соответствует типу \`PersistedQuery\`:
|
|
196
|
-
|
|
197
|
-
\`\`\`ts
|
|
198
|
-
type PersistedQuery = {
|
|
199
|
-
buster: string;
|
|
200
|
-
queryHash: string;
|
|
201
|
-
queryKey: QueryKey;
|
|
202
|
-
state: QueryState;
|
|
203
|
-
};
|
|
204
|
-
\`\`\`
|
|
205
|
-
|
|
206
|
-
В \`state\` лежат данные query и служебные timestamps TanStack Query, включая \`dataUpdatedAt\`.
|
|
207
|
-
|
|
208
|
-
Мы не сериализуем данные в JSON вручную:
|
|
209
|
-
|
|
210
|
-
\`\`\`ts
|
|
211
|
-
serialize: (query) => query,
|
|
212
|
-
deserialize: (query) => query
|
|
213
|
-
\`\`\`
|
|
214
|
-
|
|
215
|
-
IndexedDB умеет хранить structured clone, поэтому можно сохранять объект напрямую. Это уменьшает лишнюю сериализацию больших справочников.
|
|
216
|
-
|
|
217
|
-
### Жизненный цикл query
|
|
218
|
-
|
|
219
|
-
Когда компонент вызывает \`useQuery\` с \`meta: persistedQueryMeta\`, происходит такой сценарий:
|
|
220
|
-
|
|
221
|
-
1. TanStack Query создаёт query в памяти.
|
|
222
|
-
2. \`persisterFn\` проверяет \`meta.persist\`.
|
|
223
|
-
3. Если данных в памяти ещё нет, persister пробует прочитать запись из IndexedDB по \`queryHash\`.
|
|
224
|
-
4. Если запись найдена, не протухла и совпадает с \`buster\`, данные возвращаются из IndexedDB.
|
|
225
|
-
5. Если восстановленные данные stale, TanStack Query запускает фоновый refetch.
|
|
226
|
-
6. Если записи нет или она невалидна, выполняется обычный \`queryFn\`.
|
|
227
|
-
7. После успешного \`queryFn\` persister сохраняет результат в IndexedDB.
|
|
228
|
-
|
|
229
|
-
Таким образом, persistence не делает отдельный общий hydrate всего приложения на старте. Query восстанавливается лениво, только когда она реально нужна.
|
|
230
|
-
|
|
231
|
-
### Fresh, stale и maxAge
|
|
232
|
-
|
|
233
|
-
Важные настройки:
|
|
234
|
-
|
|
235
|
-
\`\`\`ts
|
|
236
|
-
export const REACT_QUERY_PERSISTENCE_MAX_AGE = 90 * 24 * 60 * 60 * 1000;
|
|
237
|
-
|
|
238
|
-
experimental_createQueryPersister({
|
|
239
|
-
maxAge: REACT_QUERY_PERSISTENCE_MAX_AGE,
|
|
240
|
-
refetchOnRestore: true
|
|
241
|
-
});
|
|
242
|
-
\`\`\`
|
|
243
|
-
|
|
244
|
-
\`maxAge\` — максимальный возраст persistent записи. Сейчас он равен 90 дням: это позволяет IndexedDB постепенно очистить старые ключи после смены \`buildId\`.
|
|
245
|
-
|
|
246
|
-
\`staleTime\` остаётся настройкой конкретной query:
|
|
247
|
-
|
|
248
|
-
- если восстановленные данные ещё fresh, \`queryFn\` не вызывается сразу;
|
|
249
|
-
- если восстановленные данные stale, они могут быть показаны из IndexedDB, а затем обновятся фоновым refetch;
|
|
250
|
-
- если запись старше текущего \`maxAge\`, она не будет использоваться.
|
|
251
|
-
|
|
252
|
-
Пример: \`useODataCollectionQuery\` имеет \`staleTime\` 2 часа и persistent \`maxAge\` 90 дней. Значит:
|
|
253
|
-
|
|
254
|
-
- через 2 часа данные восстановятся и не пойдут в сеть сразу;
|
|
255
|
-
- после 2 часов данные восстановятся, но TanStack Query сможет запустить refetch;
|
|
256
|
-
- после 90 дней запись не будет использоваться и сможет быть очищена persister-ом.
|
|
257
|
-
|
|
258
|
-
Для OData metadata и справочников свежесть дополнительно контролируется technical query: \`metadata-version\` и \`collection-updates\`.
|
|
259
|
-
|
|
260
|
-
### Cache busting
|
|
261
|
-
|
|
262
|
-
Для принудительной инвалидции старого persistent cache используется \`buster\`:
|
|
263
|
-
|
|
264
|
-
\`\`\`ts
|
|
265
|
-
export const REACT_QUERY_PERSISTENCE_BUSTER = "arm-rq-persist-v3";
|
|
266
|
-
\`\`\`
|
|
267
|
-
|
|
268
|
-
Если формат persisted данных или правила кэширования меняются несовместимо, нужно поднять версию, например:
|
|
269
|
-
|
|
270
|
-
\`\`\`ts
|
|
271
|
-
export const REACT_QUERY_PERSISTENCE_BUSTER = "arm-rq-persist-v4";
|
|
272
|
-
\`\`\`
|
|
273
|
-
|
|
274
|
-
После этого старые записи с \`v3\` будут отброшены при чтении.
|
|
275
|
-
|
|
276
|
-
### Как добавить persistence для новой справочной query
|
|
277
|
-
|
|
278
|
-
Если query действительно является справочной и её безопасно хранить между перезагрузками, добавьте \`meta: persistedQueryMeta\`:
|
|
279
|
-
|
|
280
|
-
\`\`\`ts
|
|
281
|
-
import { useQuery } from "@tanstack/react-query";
|
|
282
|
-
|
|
283
|
-
import { persistedQueryMeta } from "@/shared/lib";
|
|
284
|
-
|
|
285
|
-
export function useDictionaryQuery(service: string) {
|
|
286
|
-
return useQuery({
|
|
287
|
-
queryKey: ["dictionary", service],
|
|
288
|
-
queryFn: () => fetchDictionary(service),
|
|
289
|
-
meta: persistedQueryMeta,
|
|
290
|
-
staleTime: 1000 * 60 * 60 * 8,
|
|
291
|
-
gcTime: 1000 * 60 * 60
|
|
292
|
-
});
|
|
293
|
-
}
|
|
294
|
-
\`\`\`
|
|
295
|
-
|
|
296
|
-
Для \`queryOptions\`:
|
|
297
|
-
|
|
298
|
-
\`\`\`ts
|
|
299
|
-
import { queryOptions } from "@tanstack/react-query";
|
|
300
|
-
|
|
301
|
-
import { persistedQueryMeta } from "@/shared/lib";
|
|
302
|
-
|
|
303
|
-
export const dictionaryQueryOptions = (service: string) =>
|
|
304
|
-
queryOptions({
|
|
305
|
-
queryKey: ["dictionary", service],
|
|
306
|
-
queryFn: () => fetchDictionary(service),
|
|
307
|
-
meta: persistedQueryMeta,
|
|
308
|
-
staleTime: 1000 * 60 * 60 * 8
|
|
309
|
-
});
|
|
310
|
-
\`\`\`
|
|
311
|
-
|
|
312
|
-
Перед добавлением проверьте:
|
|
313
|
-
|
|
314
|
-
- данные не содержат персональные transient-состояния;
|
|
315
|
-
- query key стабилен и включает все параметры, влияющие на результат;
|
|
316
|
-
- \`staleTime\` соответствует допустимой свежести данных;
|
|
317
|
-
- объём данных ожидаемо подходит для IndexedDB;
|
|
318
|
-
- мутации или внешние события корректно инвалидируют эту query при изменении справочника.
|
|
319
|
-
|
|
320
|
-
### Чего не стоит сохранять
|
|
321
|
-
|
|
322
|
-
Не включайте \`persistedQueryMeta\` для:
|
|
323
|
-
|
|
324
|
-
- данных текущей формы или черновиков UI;
|
|
325
|
-
- результатов поиска с высокоэнтропийными параметрами;
|
|
326
|
-
- персональных списков, которые часто меняются и должны всегда приходить с сервера;
|
|
327
|
-
- данных с короткой жизнью, где stale-результат хуже повторного запроса;
|
|
328
|
-
- больших таблиц, которые ещё не оформлены как отдельные TanStack queries.
|
|
329
|
-
|
|
330
|
-
### Отладка в браузере
|
|
331
|
-
|
|
332
|
-
Проверить записи можно в DevTools:
|
|
333
|
-
|
|
334
|
-
1. Открыть \`Application\`.
|
|
335
|
-
2. Перейти в \`IndexedDB\`.
|
|
336
|
-
3. Найти database текущего system/client контекста.
|
|
337
|
-
4. Открыть object store \`queries\`.
|
|
338
|
-
5. Проверить ключи с prefix \`<system>:cache\`.
|
|
339
|
-
|
|
340
|
-
Если нужно сбросить persistent cache вручную, можно удалить database текущего system/client контекста в DevTools.
|
|
341
|
-
|
|
342
|
-
### Тесты
|
|
343
|
-
|
|
344
|
-
Тесты находятся в [persistence.test.ts](/src/shared/lib/query-client/persistence.test.ts) и [queryPersistence.test.ts](/src/shared/api/odata/queryPersistence.test.ts).
|
|
345
|
-
|
|
346
|
-
Они проверяют:
|
|
347
|
-
|
|
348
|
-
- сохранение, чтение, удаление и перечисление записей IndexedDB storage;
|
|
349
|
-
- opt-in фильтр \`meta.persist === true\`;
|
|
350
|
-
- что per-query persister сохраняет только помеченные query;
|
|
351
|
-
- что \`QueryClient\` подключает persister только при доступном \`indexedDB\`;
|
|
352
|
-
- что OData metadata query помечена \`persistedQueryMeta\`.
|
|
353
|
-
|
|
354
|
-
Целевой запуск:
|
|
355
|
-
|
|
356
|
-
\`\`\`bash
|
|
357
|
-
npx vitest src/shared/lib/query-client src/shared/api/odata --run
|
|
358
|
-
\`\`\`
|
|
359
|
-
|
|
360
|
-
## Синхронизация кэша React Query между вкладками
|
|
361
|
-
|
|
362
|
-
## Назначение
|
|
363
|
-
|
|
364
|
-
Модуль [broadcast.ts](/src/shared/lib/query-client/broadcast.ts) синхронизирует клиентский кэш между вкладками одного браузера.
|
|
365
|
-
|
|
366
|
-
Он решает две разные задачи:
|
|
367
|
-
|
|
368
|
-
- синхронизирует состояние \`QueryCache\` через \`broadcastQueryClient\`;
|
|
369
|
-
- автоматически рассылает \`invalidateQueries\` через прикладной events-канал, потому что TanStack broadcast не передаёт invalidation-события;
|
|
370
|
-
- поддерживает ручные события \`invalidate\` и \`setQueryData\`, когда нужна явная команда другим вкладкам.
|
|
371
|
-
|
|
372
|
-
Это полезно для сценариев, где пользователь держит открытыми несколько вкладок ARM и ожидает, что изменения в одной вкладке быстро отразятся в остальных.
|
|
373
|
-
|
|
374
|
-
## Как это устроено
|
|
375
|
-
|
|
376
|
-
Модуль использует два \`BroadcastChannel\`:
|
|
377
|
-
|
|
378
|
-
- \`queriesChannel\`:
|
|
379
|
-
нужен для низкоуровневой синхронизации кэша TanStack Query через \`@tanstack/query-broadcast-client-experimental\`;
|
|
380
|
-
- \`eventsChannel\`:
|
|
381
|
-
нужен для наших прикладных событий, которые описаны типом \`CacheSyncEvent\`, и для автоматической рассылки локальных \`invalidateQueries\`.
|
|
382
|
-
|
|
383
|
-
Каждая вкладка при инициализации получает собственный \`tabId\`. Это позволяет:
|
|
384
|
-
|
|
385
|
-
- не обрабатывать свои же сообщения повторно;
|
|
386
|
-
- не зацикливать локальные обновления.
|
|
387
|
-
|
|
388
|
-
\`broadcastQueryClient\` передаёт успешные обновления query data: обычный \`fetchQuery\`, \`useQuery\` после успешной загрузки и \`setQueryData\`. Но \`queryClient.invalidateQueries(...)\` в TanStack Query создаёт action \`invalidate\`, а пакет \`@tanstack/query-broadcast-client-experimental\` его не отправляет. Поэтому wrapper дополнительно подписывается на \`QueryCache\` и рассылает invalidation по \`eventsChannel\`.
|
|
389
|
-
|
|
390
|
-
## Поддерживаемые события
|
|
391
|
-
|
|
392
|
-
### \`invalidate\`
|
|
393
|
-
|
|
394
|
-
Инвалидирует один или несколько query key в других вкладках.
|
|
395
|
-
|
|
396
|
-
Форма:
|
|
397
|
-
|
|
398
|
-
\`\`\`ts
|
|
399
|
-
{
|
|
400
|
-
type: "invalidate",
|
|
401
|
-
keys: QueryKey[],
|
|
402
|
-
refetchType?: "none" | "all" | "active" | "inactive"
|
|
403
|
-
}
|
|
404
|
-
\`\`\`
|
|
405
|
-
|
|
406
|
-
Поведение:
|
|
407
|
-
|
|
408
|
-
- для каждого \`queryKey\` вызывается \`queryClient.invalidateQueries\`;
|
|
409
|
-
- если \`refetchType\` не передан, используется \`"none"\`.
|
|
410
|
-
|
|
411
|
-
### \`setQueryData\`
|
|
412
|
-
|
|
413
|
-
Принудительно обновляет данные конкретного query key в других вкладках.
|
|
414
|
-
|
|
415
|
-
Форма:
|
|
416
|
-
|
|
417
|
-
\`\`\`ts
|
|
418
|
-
{
|
|
419
|
-
type: "setQueryData",
|
|
420
|
-
key: QueryKey,
|
|
421
|
-
data: unknown
|
|
422
|
-
}
|
|
423
|
-
\`\`\`
|
|
424
|
-
|
|
425
|
-
Поведение:
|
|
426
|
-
|
|
427
|
-
- в получателе вызывается \`queryClient.setQueryData(key, data)\`.
|
|
428
|
-
|
|
429
|
-
## Публичный API
|
|
430
|
-
|
|
431
|
-
### \`installReactQueryBroadcast(queryClient, opts)\`
|
|
432
|
-
|
|
433
|
-
Инициализирует синхронизацию и возвращает функцию \`broadcast\`.
|
|
434
|
-
|
|
435
|
-
Параметры:
|
|
436
|
-
|
|
437
|
-
- \`queryClient\`: экземпляр \`QueryClient\`;
|
|
438
|
-
- \`opts.queriesChannel\`: имя канала синхронизации query cache;
|
|
439
|
-
- \`opts.eventsChannel\`: имя канала прикладных событий.
|
|
440
|
-
|
|
441
|
-
Возвращает:
|
|
442
|
-
|
|
443
|
-
\`\`\`ts
|
|
444
|
-
{
|
|
445
|
-
broadcast: (event: CacheSyncEvent) => void,
|
|
446
|
-
cleanup: () => void
|
|
447
|
-
}
|
|
448
|
-
\`\`\`
|
|
449
|
-
|
|
450
|
-
Если код выполняется вне браузера, функция возвращает no-op реализацию и ничего не подписывает.
|
|
451
|
-
|
|
452
|
-
### \`setBroadcastFn(fn)\`
|
|
453
|
-
|
|
454
|
-
Сохраняет глобальную функцию-рассылку. Обычно вызывается один раз при старте приложения после \`installReactQueryBroadcast\`.
|
|
455
|
-
|
|
456
|
-
### \`broadcastCacheEvent(event)\`
|
|
457
|
-
|
|
458
|
-
Упрощённый способ отправить событие из любого места приложения, не передавая \`broadcast\` вручную по слоям.
|
|
459
|
-
|
|
460
|
-
## Текущая инициализация в проекте
|
|
461
|
-
|
|
462
|
-
Инициализация выполняется в [router.tsx](/src/app/router.tsx#L34):
|
|
463
|
-
|
|
464
|
-
\`\`\`ts
|
|
465
|
-
const { broadcast } = installReactQueryBroadcast(queryClient, createQueryCacheBroadcastChannelNames());
|
|
466
|
-
|
|
467
|
-
setBroadcastFn(broadcast);
|
|
468
|
-
\`\`\`
|
|
469
|
-
|
|
470
|
-
Это означает:
|
|
471
|
-
|
|
472
|
-
- синхронизация включается один раз на всё SPA;
|
|
473
|
-
- prefix каналов берётся из \`VITE_QUERY_CACHE_BROADCAST_CHANNEL_PREFIX\`;
|
|
474
|
-
- любые части приложения могут использовать \`broadcastCacheEvent(...)\`.
|
|
475
|
-
- обычные успешные query updates и локальные invalidation-события синхронизируются без ручных вызовов в feature-коде.
|
|
476
|
-
|
|
477
|
-
## Рекомендованные сценарии использования
|
|
478
|
-
|
|
479
|
-
### После обычного query update
|
|
480
|
-
|
|
481
|
-
Обычный \`queryClient.setQueryData\` уже синхронизируется через \`broadcastQueryClient\`. Дополнительный ручной \`broadcastCacheEvent({ type: "setQueryData" })\` нужен только если вызывающий код сознательно хочет отправить команду через прикладной events-канал.
|
|
482
|
-
|
|
483
|
-
\`\`\`ts
|
|
484
|
-
queryClient.setQueryData(["tiles"], nextTiles);
|
|
485
|
-
\`\`\`
|
|
486
|
-
|
|
487
|
-
### Принудительная отправка данных
|
|
488
|
-
|
|
489
|
-
\`\`\`ts
|
|
490
|
-
broadcastCacheEvent({
|
|
491
|
-
type: "setQueryData",
|
|
492
|
-
key: ["tiles"],
|
|
493
|
-
data: nextTiles
|
|
494
|
-
});
|
|
495
|
-
\`\`\`
|
|
496
|
-
|
|
497
|
-
### После мутации, когда нужно мягко пометить данные устаревшими
|
|
498
|
-
|
|
499
|
-
Обычный \`queryClient.invalidateQueries(...)\` теперь автоматически передаётся другим вкладкам с \`refetchType: "none"\`.
|
|
500
|
-
|
|
501
|
-
Ручной вызов нужен, если требуется другой \`refetchType\` или нужно отправить сразу несколько ключей одной командой:
|
|
502
|
-
|
|
503
|
-
\`\`\`ts
|
|
504
|
-
broadcastCacheEvent({
|
|
505
|
-
type: "invalidate",
|
|
506
|
-
keys: [["tiles"], ["menu"]],
|
|
507
|
-
refetchType: "none"
|
|
508
|
-
});
|
|
509
|
-
\`\`\`
|
|
510
|
-
|
|
511
|
-
### Когда нужно обновить только неактивные запросы
|
|
512
|
-
|
|
513
|
-
\`\`\`ts
|
|
514
|
-
broadcastCacheEvent({
|
|
515
|
-
type: "invalidate",
|
|
516
|
-
keys: [["views", appId]],
|
|
517
|
-
refetchType: "inactive"
|
|
518
|
-
});
|
|
519
|
-
\`\`\`
|
|
520
|
-
|
|
521
|
-
## Ограничения и важные замечания
|
|
522
|
-
|
|
523
|
-
- Каналы работают только в браузерном окружении.
|
|
524
|
-
- Сообщения синхронизируются только между вкладками одного origin.
|
|
525
|
-
- Модуль не делает сериализацию “умнее”, чем \`BroadcastChannel\`. В \`data\` лучше передавать простые сериализуемые структуры.
|
|
526
|
-
- Runtime-проверки в модуле специально консервативные: невалидные сообщения просто игнорируются.
|
|
527
|
-
- \`broadcastQueryClient\` остаётся экспериментальной зависимостью TanStack, поэтому прикладные события \`invalidate\` и \`setQueryData\` у нас выделены отдельно и не завязаны только на её внутреннее поведение.
|
|
528
|
-
- Автоматическая invalidation отправляет конкретные \`queryKey\` уже найденных query. Широкий \`queryClient.invalidateQueries()\` в одной вкладке превращается в набор точечных invalidation-событий для query, которые реально есть в её кеше.
|
|
529
|
-
|
|
530
|
-
## Как проверить
|
|
531
|
-
|
|
532
|
-
Автоматическая проверка:
|
|
533
|
-
|
|
534
|
-
\`\`\`bash
|
|
535
|
-
npm run test -- src/shared/lib/query-client/broadcast.test.ts src/shared/lib/query-client/broadcast.integration.test.ts
|
|
536
|
-
\`\`\`
|
|
537
|
-
|
|
538
|
-
Что она доказывает:
|
|
539
|
-
|
|
540
|
-
- \`broadcast.test.ts\` проверяет wrapper, ручные events и автоматическую передачу \`invalidateQueries\`;
|
|
541
|
-
- \`broadcast.integration.test.ts\` использует реальный \`broadcastQueryClient\` из TanStack и подтверждает, что успешный \`setQueryData\` в одном \`QueryClient\` появляется во втором.
|
|
542
|
-
|
|
543
|
-
Ручная проверка в браузере:
|
|
544
|
-
|
|
545
|
-
1. Открыть одно и то же приложение в двух вкладках одного origin.
|
|
546
|
-
2. Включить React Query Devtools в обеих вкладках.
|
|
547
|
-
3. В первой вкладке открыть страницу, которая грузит metadata или справочник.
|
|
548
|
-
4. Во второй вкладке проверить, что query с тем же key появился или обновил \`dataUpdatedAt\` без собственной загрузки страницы.
|
|
549
|
-
5. В первой вкладке выполнить действие, которое вызывает \`invalidateQueries\` для видимого query.
|
|
550
|
-
6. Во второй вкладке убедиться, что тот же query стал stale или запустил refetch, если у него есть активный observer и выбранный \`refetchType\` это допускает.
|
|
551
|
-
|
|
552
|
-
## Что покрыто тестами
|
|
553
|
-
|
|
554
|
-
Тесты находятся в [broadcast.test.ts](/src/shared/lib/query-client/broadcast.test.ts) и [broadcast.integration.test.ts](/src/shared/lib/query-client/broadcast.integration.test.ts).
|
|
555
|
-
|
|
556
|
-
Они проверяют:
|
|
557
|
-
|
|
558
|
-
- no-op поведение вне браузера;
|
|
559
|
-
- вызов \`broadcastQueryClient\` с правильным каналом;
|
|
560
|
-
- передачу \`invalidate\`, включая \`refetchType: "inactive"\`;
|
|
561
|
-
- передачу \`setQueryData\`;
|
|
562
|
-
- автоматическую передачу локального \`invalidateQueries\`;
|
|
563
|
-
- реальную синхронизацию query data через TanStack broadcast;
|
|
564
|
-
- игнорирование невалидных входящих сообщений;
|
|
565
|
-
- работу \`broadcastCacheEvent\` через установленный handler.
|
|
566
|
-
`}));function l(e){return(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(i,{title:`Документация/shared/lib/queryClient`}),`
|
|
567
|
-
`,(0,d.jsx)(r,{children:s})]})}function u(e={}){let{wrapper:t}={...n(),...e.components};return t?(0,d.jsx)(t,{...e,children:(0,d.jsx)(l,{...e})}):l(e)}var d;e((()=>{d=t(),o(),a(),c()}))();export{u as default};
|