@ryuzaki13/react-foundation-ui 1.8.11 → 1.8.13
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/chunks/defaultRenderers-u_Vep6Pj.js.map +1 -1
- package/dist/chunks/multi-select-DtmRtX6v.js.map +1 -1
- package/dist/chunks/select-MN6zDPKM.js.map +1 -1
- package/dist/chunks/useODataSelectBase-DR4PrY1j.js.map +1 -1
- package/dist/multi-select/model/useODataMultiSelect.d.ts +1 -1
- package/dist/multi-select/model/useODataMultiSelect.d.ts.map +1 -1
- package/dist/multi-select/ui/MultiSelect.d.ts +1 -1
- package/dist/multi-select/ui/MultiSelect.d.ts.map +1 -1
- package/dist/multi-select/ui/SerializableMultiSelect.d.ts.map +1 -1
- package/dist/multi-select/ui/defaultRenderers.d.ts +1 -1
- package/dist/multi-select/ui/defaultRenderers.d.ts.map +1 -1
- package/dist/select/model/useODataSelect.d.ts +1 -1
- package/dist/select/model/useODataSelect.d.ts.map +1 -1
- package/dist/select/model/useODataSelectBase.d.ts +1 -1
- package/dist/select/model/useODataSelectBase.d.ts.map +1 -1
- package/dist/tree-select/index.js.map +1 -1
- package/dist/tree-select/model/buildODataTreeNodes.d.ts +1 -1
- package/dist/tree-select/model/buildODataTreeNodes.d.ts.map +1 -1
- package/package.json +3 -3
- package/storybook-static/assets/{Badge-BojMuOws.js → Badge-BFhBl7yM.js} +1 -1
- package/storybook-static/assets/{Badge.stories-C9gJRuIO.js → Badge.stories-BEu55X4s.js} +1 -1
- package/storybook-static/assets/{BadgeList-dNEWI7-O.js → BadgeList-mqmnGtRR.js} +1 -1
- package/storybook-static/assets/{Button-Bbt3JzIY.js → Button-CESdnWrO.js} +1 -1
- package/storybook-static/assets/{Button-CrTHXWYk.js → Button-_YPAu9sd.js} +1 -1
- package/storybook-static/assets/{Button.stories-BaYXOBeF.js → Button.stories-B0Y_T17B.js} +1 -1
- package/storybook-static/assets/{CalendarView-Dp0zus1o.js → CalendarView-DLuO2Ywz.js} +1 -1
- package/storybook-static/assets/{CheckBox-BiK9yWNt.js → CheckBox-CGiNmAPT.js} +1 -1
- package/storybook-static/assets/{CheckBox-UzYHaD6S.js → CheckBox-l0pbBm9z.js} +1 -1
- package/storybook-static/assets/{CheckBox.stories-C2BOiWZj.js → CheckBox.stories-ROPAnqh8.js} +1 -1
- package/storybook-static/assets/{Color-6AOWCN3U-C5S4wUlD.js → Color-6AOWCN3U-kPaRN0HS.js} +1 -1
- package/storybook-static/assets/{ContextMenu-D9EZxb7d.js → ContextMenu-Bob4DtRn.js} +1 -1
- package/storybook-static/assets/{ContextMenu-BWQln_tb.js → ContextMenu-DxfUAeJS.js} +1 -1
- package/storybook-static/assets/{ContextMenu.stories-U38zPh9_.js → ContextMenu.stories-DCJmWy5n.js} +1 -1
- package/storybook-static/assets/{CustomOptionButton-COIOrxQn.js → CustomOptionButton-DuEz9CXt.js} +1 -1
- package/storybook-static/assets/DateInput-BQ8SoeLE.js +1 -0
- package/storybook-static/assets/{DateInput-C-entb-r.js → DateInput-DmNLD4Dz.js} +1 -1
- package/storybook-static/assets/{DateInput.stories-NmUXQLDU.js → DateInput.stories-sTpYf7Ob.js} +1 -1
- package/storybook-static/assets/{DateRangePresetSelect-BM1L1KOo.js → DateRangePresetSelect-DRq4eJ2n.js} +1 -1
- package/storybook-static/assets/{DateRangePresetSelect-CAJzxaq0.js → DateRangePresetSelect-fgJfLaLO.js} +1 -1
- package/storybook-static/assets/{DateRangePresetSelect.stories-CC47XLnD.js → DateRangePresetSelect.stories-ib7Qh_BB.js} +1 -1
- package/storybook-static/assets/{Detail-CDluXtts.js → Detail-CJniLn1R.js} +1 -1
- package/storybook-static/assets/{Detail.stories-DjniLC4n.js → Detail.stories-BXjdNaL-.js} +1 -1
- package/storybook-static/assets/{Dialog-bzRSgGU7.js → Dialog-D6a_qzr3.js} +1 -1
- package/storybook-static/assets/{Dialog-bw6cHUsz.js → Dialog-DOYnnXlU.js} +1 -1
- package/storybook-static/assets/{Dialog.stories-C6Rs6s_p.js → Dialog.stories-B1cZLRK3.js} +1 -1
- package/storybook-static/assets/{Disclosure-DelA6FsQ.js → Disclosure-Chh5o_0s.js} +1 -1
- package/storybook-static/assets/{Disclosure.stories-D7yUinyb.js → Disclosure.stories-Cvdvf7V8.js} +1 -1
- package/storybook-static/assets/{DisclosureGroup-DbK7mU_Q.js → DisclosureGroup-CRnQOgVj.js} +1 -1
- package/storybook-static/assets/{DocsRenderer-JROSPFPF-v3z0zVN1.js → DocsRenderer-JROSPFPF-BBiErkeC.js} +1 -1
- package/storybook-static/assets/{DropZone-CI3NW4AC.js → DropZone-Bm5gqdi9.js} +1 -1
- package/storybook-static/assets/{DropZone-Cyy-ttEO.js → DropZone-C4L7JAlq.js} +1 -1
- package/storybook-static/assets/{DropZone.stories-S0HSpGTB.js → DropZone.stories-BhA9q8Qv.js} +1 -1
- package/storybook-static/assets/{DropdownMenu-Ct1bSZsE.js → DropdownMenu-DtZNSUHF.js} +1 -1
- package/storybook-static/assets/{ExpandableActionPanel-Oj3xlasj.js → ExpandableActionPanel-0ugXlJy_.js} +1 -1
- package/storybook-static/assets/{ExpandableActionPanel.stories-Ch7CLkpR.js → ExpandableActionPanel.stories-CLgMlA9k.js} +1 -1
- package/storybook-static/assets/{Flex-UiFm8Tkc.js → Flex-CJlia-8f.js} +1 -1
- package/storybook-static/assets/{Flex.stories-CaDiVlBD.js → Flex.stories-DCvfi1EY.js} +1 -1
- package/storybook-static/assets/{FloatingPopover-CTYV9W7T.js → FloatingPopover-CsnfPiwV.js} +1 -1
- package/storybook-static/assets/{FormattedTableCell-D-ysSR3p.js → FormattedTableCell-Dz5xWVYO.js} +1 -1
- package/storybook-static/assets/{Grid-CigBXPe2.js → Grid-C-KwTRAM.js} +1 -1
- package/storybook-static/assets/{Grid.stories-ay3z9DQZ.js → Grid.stories-CzbqknNR.js} +1 -1
- package/storybook-static/assets/{ImageCropper.stories-Dkce_ugb.js → ImageCropper.stories-DaE-gm-b.js} +1 -1
- package/storybook-static/assets/{ImageRenderer-C9_EmGBW.js → ImageRenderer-IsNCXCrZ.js} +1 -1
- package/storybook-static/assets/{ImageRenderer.stories-C7bXaNBI.js → ImageRenderer.stories-BbsjUEfJ.js} +1 -1
- package/storybook-static/assets/{ImageView.stories-D-ZzGlk8.js → ImageView.stories-DY0UITYz.js} +1 -1
- package/storybook-static/assets/{ImageViewer.stories-ItcRfxyy.js → ImageViewer.stories--9q9b9nv.js} +2 -2
- package/storybook-static/assets/{ImageViewerRuntime-eaupID36.js → ImageViewerRuntime-CNEH3XGN.js} +1 -1
- package/storybook-static/assets/{Input-op4j7Beh.js → Input-DLubbE7P.js} +1 -1
- package/storybook-static/assets/{Input-BUDNR96c.js → Input-Dw2JblYt.js} +1 -1
- package/storybook-static/assets/{Input.stories-DwulvJIg.js → Input.stories-DQeyDULG.js} +1 -1
- package/storybook-static/assets/{InputDateTime-B_cxOp6k.js → InputDateTime-BRzl8Vrt.js} +1 -1
- package/storybook-static/assets/{InputDateTime.stories-BueLF4HC.js → InputDateTime.stories-BJTj5v8J.js} +1 -1
- package/storybook-static/assets/{InputFile-DSg7sugm.js → InputFile-B8UroZji.js} +1 -1
- package/storybook-static/assets/{InputFile-C8z6TPc1.js → InputFile-DPftxjGw.js} +1 -1
- package/storybook-static/assets/{InputFile.stories-C6XSbIua.js → InputFile.stories-C7yyqHqc.js} +1 -1
- package/storybook-static/assets/{InputFiles-DoatLq3q.js → InputFiles-BQVXHVLy.js} +1 -1
- package/storybook-static/assets/{InputFiles-DeZ84Uu_.js → InputFiles-UD_9S7-N.js} +1 -1
- package/storybook-static/assets/{InputFiles.stories-BMbE8SJU.js → InputFiles.stories-DjjJS5pZ.js} +1 -1
- package/storybook-static/assets/{InputFilesList-CsfDDqaJ.js → InputFilesList-BNjijD3Y.js} +1 -1
- package/storybook-static/assets/{InputImage-yJSq98EH.js → InputImage-C-pHr-Sx.js} +1 -1
- package/storybook-static/assets/{InputImage-D_YnB2Tw.js → InputImage-DbcbqIhY.js} +1 -1
- package/storybook-static/assets/{InputImage.stories-nivUG307.js → InputImage.stories-D-TC9r9t.js} +1 -1
- package/storybook-static/assets/{InteractiveComponents-IPkC_Rkg.js → InteractiveComponents-DbhWgM9y.js} +1 -1
- package/storybook-static/assets/{InteractiveComponents.stories-D4VzVKZJ.js → InteractiveComponents.stories-B4mkVSea.js} +1 -1
- package/storybook-static/assets/{LayoutPicker-ZHkMi-LM.js → LayoutPicker-BoV_E3qt.js} +1 -1
- package/storybook-static/assets/{LayoutPicker-aMzPN5Do.js → LayoutPicker-w1EsRpYP.js} +1 -1
- package/storybook-static/assets/{LayoutPicker.stories-DAzpzxn5.js → LayoutPicker.stories--ChGnGxf.js} +1 -1
- package/storybook-static/assets/{Listbox-CR5nXC9J.js → Listbox-CzZRsr6a.js} +1 -1
- package/storybook-static/assets/{Listbox-BmfQOnrb.js → Listbox-qZdTi11b.js} +1 -1
- package/storybook-static/assets/{Listbox.stories-CeOpsKxB.js → Listbox.stories-C9k_1850.js} +1 -1
- package/storybook-static/assets/{Modal-BStp52Zo.js → Modal-DCpul8QM.js} +1 -1
- package/storybook-static/assets/{Modal.stories-CwGm5GYE.js → Modal.stories-Cy0Xd4LF.js} +1 -1
- package/storybook-static/assets/{ModalManagerProvider-B5uUXWF9.js → ModalManagerProvider-BrPVMcHV.js} +1 -1
- package/storybook-static/assets/{MultiSelect-308npb27.js → MultiSelect-BEQdl-F4.js} +1 -1
- package/storybook-static/assets/{MultiSelect-BDs02MZh.js → MultiSelect-Dy4X94E2.js} +1 -1
- package/storybook-static/assets/{MultiSelect.stories-DRi_iTp4.js → MultiSelect.stories-FuzejJmz.js} +1 -1
- package/storybook-static/assets/{NoData-ovaQEE9W.js → NoData-BsQ9EfkA.js} +1 -1
- package/storybook-static/assets/{NotificationsHost-BpeMWhLY.js → NotificationsHost-BSrODvw7.js} +1 -1
- package/storybook-static/assets/NotificationsHost.stories-DeiWspcY.js +29 -0
- package/storybook-static/assets/{ODataMultiSelect-qlft9L9L.js → ODataMultiSelect-BEz9gcd2.js} +1 -1
- package/storybook-static/assets/{ODataMultiSelect.stories-CMPIoPiy.js → ODataMultiSelect.stories-BwMgAkbE.js} +2 -2
- package/storybook-static/assets/{ODataSelect-DKBQArAK.js → ODataSelect-BgC7GHOv.js} +1 -1
- package/storybook-static/assets/{ODataSelect.stories-DxYIhtwe.js → ODataSelect.stories-DEIRAB-s.js} +2 -2
- package/storybook-static/assets/{ODataTreeMultiSelect-DAt6THP3.js → ODataTreeMultiSelect-WyZZuX0_.js} +1 -1
- package/storybook-static/assets/{ODataTreeMultiSelect.stories-CBNJP0mP.js → ODataTreeMultiSelect.stories-B6cxuagy.js} +1 -1
- package/storybook-static/assets/{ODataTreeSelect-Bzzt4CQC.js → ODataTreeSelect-OJGi3-S7.js} +1 -1
- package/storybook-static/assets/{ODataTreeSelect.stories-CWVvuqOt.js → ODataTreeSelect.stories-wGRGErCH.js} +1 -1
- package/storybook-static/assets/{OneStepScroller-BY5lz8qi.js → OneStepScroller-DycQ3RuL.js} +1 -1
- package/storybook-static/assets/{Option-Rw8xwrPg.js → Option-taxbFfjo.js} +1 -1
- package/storybook-static/assets/{OptionButton-Br48w_Zg.js → OptionButton-Q0QaPCII.js} +1 -1
- package/storybook-static/assets/{PeriodSelect-8-wpXz6w.js → PeriodSelect-DUJ2nF3F.js} +1 -1
- package/storybook-static/assets/{PeriodSelect-DxSRwKw-.js → PeriodSelect-DnM7x-uC.js} +1 -1
- package/storybook-static/assets/{PeriodSelect.stories-B-qgUzlS.js → PeriodSelect.stories-Db0bqe3J.js} +1 -1
- package/storybook-static/assets/{PickerTriggerActions-C5xmysFh.js → PickerTriggerActions-CGJd7xmR.js} +1 -1
- package/storybook-static/assets/{Popover-NJwt_vZZ.js → Popover-B6oidz5p.js} +1 -1
- package/storybook-static/assets/{Popover-Ds8PUigp.js → Popover-Tbhf8T81.js} +1 -1
- package/storybook-static/assets/{Popover.stories-CUOFA_Xf.js → Popover.stories-DE1LxZvv.js} +1 -1
- package/storybook-static/assets/{PresetRangeDateInput-DyOpbkON.js → PresetRangeDateInput-CQ5FfmrL.js} +1 -1
- package/storybook-static/assets/{PresetRangeDateInput-Xk0bOy3S.js → PresetRangeDateInput-DfgoR0My.js} +1 -1
- package/storybook-static/assets/{PresetRangeDateInput.stories-CwjUlXj0.js → PresetRangeDateInput.stories-CgoYAYBG.js} +1 -1
- package/storybook-static/assets/{PresetSelect-Ddmr0niY.js → PresetSelect-BPtAknAr.js} +1 -1
- package/storybook-static/assets/README--TpGcM95.js +110 -0
- package/storybook-static/assets/{README-MzcO5Z_P.js → README-4iBHWAP5.js} +1 -1
- package/storybook-static/assets/README-98KIgy5G.js +75 -0
- package/storybook-static/assets/README-B6II8p0W.js +154 -0
- package/storybook-static/assets/{README-CkWglKbS.js → README-B6vU5_7I.js} +1 -1
- package/storybook-static/assets/README-BFJVjjZR.js +325 -0
- package/storybook-static/assets/README-BIT4HlFP.js +441 -0
- package/storybook-static/assets/{README-DqQDgJN-.js → README-BK6Epio1.js} +1 -1
- package/storybook-static/assets/{README-DRnlD7y8.js → README-BRlPB5_k.js} +1 -1
- package/storybook-static/assets/README-BTFpEaXG.js +64 -0
- package/storybook-static/assets/README-BWhXgC_o.js +226 -0
- package/storybook-static/assets/README-BbNHvOoR.js +101 -0
- package/storybook-static/assets/README-BbunUo8b.js +118 -0
- package/storybook-static/assets/README-BmYpfZKr.js +1844 -0
- package/storybook-static/assets/README-Bu5uvhAT.js +230 -0
- package/storybook-static/assets/README-Bx6fvSBE.js +1282 -0
- package/storybook-static/assets/README-Bx6gIGiA.js +69 -0
- package/storybook-static/assets/README-ByhxsX44.js +324 -0
- package/storybook-static/assets/README-Byi1FFpw.js +98 -0
- package/storybook-static/assets/README-C3Is3a3B.js +208 -0
- package/storybook-static/assets/{README-C0BwTe5N.js → README-C6prwAXw.js} +1 -1
- package/storybook-static/assets/{README-BzVni2ve.js → README-C9S83J_G.js} +1 -1
- package/storybook-static/assets/{README-BHw6MVjD.js → README-CGgxP5Zo.js} +1 -1
- package/storybook-static/assets/README-CJ2ZVG2U.js +2124 -0
- package/storybook-static/assets/README-CNGCAm5d.js +95 -0
- package/storybook-static/assets/README-Cb_q420B.js +90 -0
- package/storybook-static/assets/README-CtIDPNJ3.js +186 -0
- package/storybook-static/assets/README-CzO3Dchr.js +64 -0
- package/storybook-static/assets/README-D0rzQthv.js +264 -0
- package/storybook-static/assets/README-DEQu7djz.js +1704 -0
- package/storybook-static/assets/README-DFihT_sm.js +296 -0
- package/storybook-static/assets/{README-CTIBG4zH.js → README-DMiWsyv_.js} +1 -1
- package/storybook-static/assets/README-DOx8lXXk.js +82 -0
- package/storybook-static/assets/{README-DzTc6XmY.js → README-DPhDjr43.js} +1 -1
- package/storybook-static/assets/{README-Dki94Nf2.js → README-D_NqWPa9.js} +1 -1
- package/storybook-static/assets/README-DhJ5Rb1w.js +355 -0
- package/storybook-static/assets/README-DlwhWCvQ.js +1146 -0
- package/storybook-static/assets/README-Dxi73a2Q.js +740 -0
- package/storybook-static/assets/README-Dycov6NP.js +583 -0
- package/storybook-static/assets/README-GTBkSG4_.js +3591 -0
- package/storybook-static/assets/README-Gfd9tLTw.js +672 -0
- package/storybook-static/assets/{README-B4zYJg6u.js → README-Kfawetke.js} +1 -1
- package/storybook-static/assets/{README-BzVHwvgo.js → README-UDBM7ZMT.js} +1 -1
- package/storybook-static/assets/{README-D-XjRtAE.js → README-VTWQxLm_.js} +1 -1
- package/storybook-static/assets/README-YHNWrTZv.js +400 -0
- package/storybook-static/assets/README-_0Otw0eD.js +448 -0
- package/storybook-static/assets/README-aw2Xu9xu.js +158 -0
- package/storybook-static/assets/README-eg1emlll.js +192 -0
- package/storybook-static/assets/README-iqQHdhZ4.js +416 -0
- package/storybook-static/assets/{README-BdPlV5nA.js → README-llxZAtCj.js} +1 -1
- package/storybook-static/assets/README-wFnEIGl4.js +95 -0
- package/storybook-static/assets/{README-Dx3cpFMr.js → README-webB1yH0.js} +1 -1
- package/storybook-static/assets/README-wtreGRCe.js +208 -0
- package/storybook-static/assets/{RadioButton-DWbkCY8u.js → RadioButton-CNOLDk_o.js} +1 -1
- package/storybook-static/assets/{RadioButton-oSvQ-gQh.js → RadioButton-Ce05_q7s.js} +1 -1
- package/storybook-static/assets/{RadioButton.stories-GNQ9XJZT.js → RadioButton.stories-CPd4lTl0.js} +1 -1
- package/storybook-static/assets/{RadioGroup-CvXjGXcV.js → RadioGroup-BtfD5Szd.js} +1 -1
- package/storybook-static/assets/{RadioGroup-eBYggurL.js → RadioGroup-Ccm7G-dv.js} +1 -1
- package/storybook-static/assets/{RadioGroup.stories-C77j_cPv.js → RadioGroup.stories-D-RRPHwi.js} +1 -1
- package/storybook-static/assets/{Scrollable-De6SdhI3.js → Scrollable-DvdBIeig.js} +1 -1
- package/storybook-static/assets/{Select-DQMoVjn4.js → Select-8PV9PBKF.js} +1 -1
- package/storybook-static/assets/{Select-Bwc0bEpt.js → Select-G04B41FM.js} +1 -1
- package/storybook-static/assets/{Select.stories-BSIJKJnM.js → Select.stories-Cf6CBhV8.js} +1 -1
- package/storybook-static/assets/{SerializableSelect-B73irNFR.js → SerializableSelect-CdQdHIVp.js} +1 -1
- package/storybook-static/assets/{SerializableSelect.stories-Z9q6g5v2.js → SerializableSelect.stories-0AKUGpbS.js} +1 -1
- package/storybook-static/assets/{SingleDateTimeInput-Dq9LcjnS.js → SingleDateTimeInput-DWT1ORhL.js} +1 -1
- package/storybook-static/assets/{SingleDateTimeInput-BHl6srqA.js → SingleDateTimeInput-DattLt6w.js} +1 -1
- package/storybook-static/assets/SingleDateTimeInput.stories-BLJV3jzV.js +48 -0
- package/storybook-static/assets/{Slider-CvM0N_kc.js → Slider-DKEI4cDd.js} +1 -1
- package/storybook-static/assets/{Slider-BiyKexKa.js → Slider-Dci-mJt_.js} +1 -1
- package/storybook-static/assets/{Slider.stories-CdHAMDmY.js → Slider.stories-Dp7oQueF.js} +1 -1
- package/storybook-static/assets/{SliderInput-DqHotbhB.js → SliderInput-BGPQmlgY.js} +1 -1
- package/storybook-static/assets/{SliderInput-Bx_oHUCV.js → SliderInput-BhjqGOKt.js} +1 -1
- package/storybook-static/assets/{SliderInput.stories-R5yDhghM.js → SliderInput.stories-DXNhRU3X.js} +1 -1
- package/storybook-static/assets/{Sortable-D7pjTHO0.js → Sortable-CMd9l1Gd.js} +1 -1
- package/storybook-static/assets/{Sortable.stories-CVLG6pSH.js → Sortable.stories-BN1cFEFJ.js} +1 -1
- package/storybook-static/assets/{Splitter-B1Du6XI2.js → Splitter-GL65TlI9.js} +1 -1
- package/storybook-static/assets/{Splitter.stories-D-FRLMCc.js → Splitter.stories-q5PlI6rB.js} +1 -1
- package/storybook-static/assets/{StateSelect-zl-yZibY.js → StateSelect-Byik5-iZ.js} +1 -1
- package/storybook-static/assets/{StateSelect-BJdUEUBc.js → StateSelect-CT0JF2V6.js} +1 -1
- package/storybook-static/assets/{StateSelect.stories-DgidR5zR.js → StateSelect.stories-pPEPmgnN.js} +1 -1
- package/storybook-static/assets/{StringToggle.stories-IucGrtIi.js → StringToggle.stories-BQlFmCE7.js} +1 -1
- package/storybook-static/assets/{Switch-BJrn2lIN.js → Switch--xGPiYk-.js} +1 -1
- package/storybook-static/assets/{Switch-5dCshvVo.js → Switch-DhaLI9CG.js} +1 -1
- package/storybook-static/assets/{Switch.stories-Dp_l3_JL.js → Switch.stories-5DisgIyj.js} +1 -1
- package/storybook-static/assets/{Table-BFAEcUde.js → Table-Bf6MicdG.js} +1 -1
- package/storybook-static/assets/{Table.stories-CohejRQv.js → Table.stories-CS7rQgj9.js} +2 -2
- package/storybook-static/assets/{Tabs-CI32QiHf.js → Tabs-B4y4y8Ap.js} +1 -1
- package/storybook-static/assets/{Tabs.stories-Cr9d9ipA.js → Tabs.stories-C0SpdGkh.js} +1 -1
- package/storybook-static/assets/{TabsBox-BlDOUDMF.js → TabsBox-C5LLLhnj.js} +1 -1
- package/storybook-static/assets/{TagInput-YZ7eSv8W.js → TagInput-D4BpuCoH.js} +1 -1
- package/storybook-static/assets/{TagInput.stories-DrOvsiI5.js → TagInput.stories-rn2wtZP_.js} +1 -1
- package/storybook-static/assets/{Text-DK4jN26J.js → Text-BhBt9e7C.js} +1 -1
- package/storybook-static/assets/{Textarea-CFh5f_lC.js → Textarea-B-Hz7ujq.js} +1 -1
- package/storybook-static/assets/{Textarea-DxPuWBZj.js → Textarea-BHHxY5sd.js} +1 -1
- package/storybook-static/assets/{Textarea.stories-CUeOGKYc.js → Textarea.stories-CZ2kWz20.js} +1 -1
- package/storybook-static/assets/{TimePanel-BUhFtwlb.js → TimePanel-Cg8fgFsn.js} +1 -1
- package/storybook-static/assets/{TimePanel.stories-CpXpMBDN.js → TimePanel.stories-BxdwtK2e.js} +1 -1
- package/storybook-static/assets/{Toggle-l2AvDbRn.js → Toggle-BWwfk9fi.js} +1 -1
- package/storybook-static/assets/{Toggle-BtApzBNH.js → Toggle-Ce9rbjBc.js} +1 -1
- package/storybook-static/assets/{Toggle.stories-Ca8otmAa.js → Toggle.stories-0fzcmzKy.js} +1 -1
- package/storybook-static/assets/{TreeMultiSelect-C9QDV63L.js → TreeMultiSelect-B06Y0lIc.js} +1 -1
- package/storybook-static/assets/{TreeMultiSelect-nXC4ZB5b.js → TreeMultiSelect-CrAdR_jM.js} +1 -1
- package/storybook-static/assets/{TreeMultiSelect.stories-6STRGJbF.js → TreeMultiSelect.stories-CAVoj56E.js} +1 -1
- package/storybook-static/assets/{TreePickerBase-Cq7fSw3x.js → TreePickerBase-qU2xPlar.js} +1 -1
- package/storybook-static/assets/{TreeSelect-CITef9rp.js → TreeSelect-BIHydJFy.js} +1 -1
- package/storybook-static/assets/{TreeSelect-rMNyu_KT.js → TreeSelect-BKnWu0C7.js} +1 -1
- package/storybook-static/assets/{TreeSelect.stories-B-Emz9yW.js → TreeSelect.stories-Dp_8ybAf.js} +1 -1
- package/storybook-static/assets/{TreeTable-CLiP0td3.js → TreeTable-pVXjU9dG.js} +1 -1
- package/storybook-static/assets/{TreeTable.stories-DJb9qt8k.js → TreeTable.stories-CV_8Ui6R.js} +2 -2
- package/storybook-static/assets/{blocks-DndFRxxW.js → blocks-BY40djCc.js} +3 -3
- package/storybook-static/assets/{check-CLkTJVXe.js → check-CVkPTDzp.js} +1 -1
- package/storybook-static/assets/{chevron-down-miCejSEn.js → chevron-down-BtNO4Vhe.js} +1 -1
- package/storybook-static/assets/{chevron-left-DhQIPej2.js → chevron-left-kceSK3sZ.js} +1 -1
- package/storybook-static/assets/{chevron-right-DfBBx-fr.js → chevron-right-BA_LO2El.js} +1 -1
- package/storybook-static/assets/{chunk-W22LQPXL-IdwKKJUw.js → chunk-W22LQPXL-yJiFPv6e.js} +1 -1
- package/storybook-static/assets/{circle-alert-DOmVf8am.js → circle-alert-B2m4a1zz.js} +1 -1
- package/storybook-static/assets/{circle-check-e7eSQ2VD.js → circle-check-Cfjhotlm.js} +1 -1
- package/storybook-static/assets/{components-Bm4Cw8Ap.js → components-D6yV8PLX.js} +3 -3
- package/storybook-static/assets/{contextMenu-DpIKeJju.js → contextMenu-B0pQBIW0.js} +1 -1
- package/storybook-static/assets/{defaultRenderers-m21aWJXz.js → defaultRenderers-DfmnIuod.js} +1 -1
- package/storybook-static/assets/{download-eAKjms6q.js → download-Lba8elK9.js} +1 -1
- package/storybook-static/assets/{floating-ui.react-DmilONq6.js → floating-ui.react-BFNvfMpU.js} +1 -1
- package/storybook-static/assets/formatters-D33Uh3si-CxrG0jsB.js +1 -0
- package/storybook-static/assets/foundationApi-DZhnQ2cC.js +59 -0
- package/storybook-static/assets/foundationLib-CoVTo22U.js +30 -0
- package/storybook-static/assets/{hooks-RI5_2AXI.js → hooks-Cc6eXN6U.js} +1 -1
- package/storybook-static/assets/iframe-BXM-JBuH.js +1 -0
- package/storybook-static/assets/{iframe-Sr0umHM6.js → iframe-o7sH2IXC.js} +4 -4
- package/storybook-static/assets/{info-DhJTzwcL.js → info-BpsVP_dM.js} +1 -1
- package/storybook-static/assets/odata-CXsbxsRY.js +1 -0
- package/storybook-static/assets/odata-service-CWkHASdw-DlmSiioz.js +3 -0
- package/storybook-static/assets/{odataStoryFixtures-lgnWIUp7.js → odataStoryFixtures-Dj_bzRqh.js} +1 -1
- package/storybook-static/assets/{react-YFbUKK0m.js → react-DeJ0JTHb.js} +1 -1
- package/storybook-static/assets/{refresh-cw-C7WnxX9M.js → refresh-cw-BvGyjEXe.js} +1 -1
- package/storybook-static/assets/{settings-2-0NVvyKQl.js → settings-2-BdXxnHos.js} +1 -1
- package/storybook-static/assets/{sortable-DDGG-Zfs.js → sortable-XkyN-9r5.js} +1 -1
- package/storybook-static/assets/{syntaxhighlighter-QEQV7K2Y-CxWm8nc8.js → syntaxhighlighter-QEQV7K2Y-Cafn3LV1.js} +1 -1
- package/storybook-static/assets/{trash-2-BnceCuhg.js → trash-2-uPH9-fND.js} +1 -1
- package/storybook-static/assets/{triangle-alert-MPi3GVgt.js → triangle-alert-tT01vSMw.js} +1 -1
- package/storybook-static/assets/{useODataSelectBase-hmjK6chS.js → useODataSelectBase-B2LlOwPZ.js} +1 -1
- package/storybook-static/assets/useODataTreeData-CU7Rqcb9.js +1 -0
- package/storybook-static/assets/{usePickerQuery-CtsGhieD.js → usePickerQuery-D8GHQ6KR.js} +1 -1
- package/storybook-static/assets/{usePickerTriggerController-EaI8W2G0.js → usePickerTriggerController-CcK1jmDy.js} +1 -1
- package/storybook-static/assets/{x-CqPSvWfo.js → x-BlAURbAH.js} +1 -1
- package/storybook-static/iframe.html +2 -2
- package/storybook-static/index.json +1 -1
- package/storybook-static/project.json +1 -1
- package/storybook-static/assets/DateInput-05Iy69_a.js +0 -1
- package/storybook-static/assets/NotificationsHost.stories-CgbFboVD.js +0 -29
- package/storybook-static/assets/SingleDateTimeInput.stories-C2RuBRAF.js +0 -48
- package/storybook-static/assets/async-SjiCjIjO.js +0 -625
- package/storybook-static/assets/formatters-CBgrBeSA-CqB1pZxS.js +0 -1
- package/storybook-static/assets/foundationLib-DRrox3tN.js +0 -25
- package/storybook-static/assets/iframe-DQo-3eW2.js +0 -1
- package/storybook-static/assets/odata-DhISMZkE.js +0 -1
- package/storybook-static/assets/odata-service-B6TxBSLm-Bq8Ya67E.js +0 -3
- package/storybook-static/assets/odataFetchFn-Dv6Xi5CI.js +0 -763
- package/storybook-static/assets/persisted-CUFiw53N.js +0 -600
- package/storybook-static/assets/useODataTreeData-CKuavbWc.js +0 -1
|
@@ -0,0 +1,416 @@
|
|
|
1
|
+
import{n as e}from"./rolldown-runtime-DkW27tQK.js";import{n as t}from"./iframe-o7sH2IXC.js";import{i as n,r}from"./react-Bl2r1tuC.js";import{l as i,m as a}from"./blocks-BY40djCc.js";function o(e){let t={code:`code`,h1:`h1`,h2:`h2`,h3:`h3`,li:`li`,ol:`ol`,p:`p`,pre:`pre`,strong:`strong`,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/Errors/Error Report`}),`
|
|
2
|
+
`,(0,c.jsx)(t.h1,{id:`error-report`,children:`Error Report`}),`
|
|
3
|
+
`,(0,c.jsxs)(t.p,{children:[`Модуль `,(0,c.jsx)(t.code,{children:`@ryuzaki13/react-foundation-lib/error-report`}),` собирает клиентскую диагностику ошибки в структурированный draft и временно хранит последние drafts в `,(0,c.jsx)(t.code,{children:`sessionStorage`}),`.`]}),`
|
|
4
|
+
`,(0,c.jsx)(t.p,{children:`Он умеет объединить:`}),`
|
|
5
|
+
`,(0,c.jsxs)(t.ul,{children:[`
|
|
6
|
+
`,(0,c.jsx)(t.li,{children:`нормализованную ошибку и stack trace;`}),`
|
|
7
|
+
`,(0,c.jsx)(t.li,{children:`сведения о browser/build;`}),`
|
|
8
|
+
`,(0,c.jsx)(t.li,{children:`URL и viewport;`}),`
|
|
9
|
+
`,(0,c.jsx)(t.li,{children:`последние действия пользователя — breadcrumbs;`}),`
|
|
10
|
+
`,(0,c.jsx)(t.li,{children:`состояние TanStack Query без полного query data;`}),`
|
|
11
|
+
`,(0,c.jsx)(t.li,{children:`технические сведения о persisted queries;`}),`
|
|
12
|
+
`,(0,c.jsx)(t.li,{children:`контекст React/runtime/transport;`}),`
|
|
13
|
+
`,(0,c.jsxs)(t.li,{children:[`lifecycle доставки: `,(0,c.jsx)(t.code,{children:`pending`}),`, `,(0,c.jsx)(t.code,{children:`sending`}),`, `,(0,c.jsx)(t.code,{children:`sent`}),`, `,(0,c.jsx)(t.code,{children:`failed`}),`.`]}),`
|
|
14
|
+
`]}),`
|
|
15
|
+
`,(0,c.jsxs)(t.p,{children:[`Важная граница: `,(0,c.jsx)(t.strong,{children:`lib-пакет не отправляет отчёт на сервер`}),`. Он формирует draft и предоставляет точки подключения. Авторизация, HTTP/API delivery, retry, пользовательское согласие и UI принадлежат приложению либо API-пакету.`]}),`
|
|
16
|
+
`,(0,c.jsx)(t.h2,{id:`установка`,children:`Установка`}),`
|
|
17
|
+
`,(0,c.jsx)(t.p,{children:`Модуль интегрируется с TanStack Query и query persistence.`}),`
|
|
18
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-bash`,children:`npm install @ryuzaki13/react-foundation-lib \\
|
|
19
|
+
@tanstack/react-query \\
|
|
20
|
+
@tanstack/query-persist-client-core
|
|
21
|
+
`})}),`
|
|
22
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`import {
|
|
23
|
+
captureRuntimeErrorReport,
|
|
24
|
+
createErrorInfo,
|
|
25
|
+
installErrorReportBrowserBreadcrumbs,
|
|
26
|
+
setErrorReportRuntimeErrorReporter,
|
|
27
|
+
type ErrorReportDraft
|
|
28
|
+
} from "@ryuzaki13/react-foundation-lib/error-report";
|
|
29
|
+
`})}),`
|
|
30
|
+
`,(0,c.jsx)(t.h2,{id:`ментальная-модель`,children:`Ментальная модель`}),`
|
|
31
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-text`,children:`исходная ошибка
|
|
32
|
+
→ capture-функция
|
|
33
|
+
→ нормализация + diagnostics + breadcrumbs
|
|
34
|
+
→ ErrorReportDraft(status = pending)
|
|
35
|
+
→ sessionStorage, максимум 10 drafts
|
|
36
|
+
→ app/API delivery
|
|
37
|
+
→ updateErrorReportDraft(status = sending/sent/failed)
|
|
38
|
+
`})}),`
|
|
39
|
+
`,(0,c.jsx)(t.p,{children:`Сбор отчёта — дополнительный диагностический сценарий. Ошибка репортера не должна заменять исходную ошибку и ломать основной пользовательский поток.`}),`
|
|
40
|
+
`,(0,c.jsx)(t.h2,{id:`когда-сбор-включён`,children:`Когда сбор включён`}),`
|
|
41
|
+
`,(0,c.jsx)(t.h3,{id:`iserrorreportingenabledoptions`,children:(0,c.jsx)(t.code,{children:`isErrorReportingEnabled(options?)`})}),`
|
|
42
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`isErrorReportingEnabled();
|
|
43
|
+
isErrorReportingEnabled({ isDev: false });
|
|
44
|
+
`})}),`
|
|
45
|
+
`,(0,c.jsxs)(t.p,{children:[`Возвращает `,(0,c.jsx)(t.code,{children:`true`}),` только в браузере и только вне dev-режима. По умолчанию режим читается из compile-time `,(0,c.jsx)(t.code,{children:`__DEV__`}),`.`]}),`
|
|
46
|
+
`,(0,c.jsx)(t.p,{children:`Следствия:`}),`
|
|
47
|
+
`,(0,c.jsxs)(t.ul,{children:[`
|
|
48
|
+
`,(0,c.jsx)(t.li,{children:`при SSR draft не создаётся;`}),`
|
|
49
|
+
`,(0,c.jsxs)(t.li,{children:[`в development capture-функции возвращают `,(0,c.jsx)(t.code,{children:`undefined`}),`;`]}),`
|
|
50
|
+
`,(0,c.jsxs)(t.li,{children:[`тест может явно передать `,(0,c.jsx)(t.code,{children:`{ isDev: false }`}),` только в эту функцию, но остальные capture-функции всё равно используют общий `,(0,c.jsx)(t.code,{children:`__DEV__`}),`.`]}),`
|
|
51
|
+
`]}),`
|
|
52
|
+
`,(0,c.jsx)(t.h2,{id:`compile-time-константы`,children:`Compile-time константы`}),`
|
|
53
|
+
`,(0,c.jsx)(t.p,{children:`Потребитель должен определить:`}),`
|
|
54
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`declare const __DEV__: boolean;
|
|
55
|
+
declare const __APP_ID__: string;
|
|
56
|
+
declare const __APP_BUILD_ID__: string;
|
|
57
|
+
`})}),`
|
|
58
|
+
`,(0,c.jsxs)(t.p,{children:[(0,c.jsx)(t.code,{children:`__APP_ID__`}),` входит в ключи `,(0,c.jsx)(t.code,{children:`sessionStorage`}),`, а `,(0,c.jsx)(t.code,{children:`__APP_BUILD_ID__`}),` помогает связать ошибку с деплоем.`]}),`
|
|
59
|
+
`,(0,c.jsx)(t.p,{children:`Пример Vite:`}),`
|
|
60
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`define: {
|
|
61
|
+
__DEV__: JSON.stringify(mode !== "production"),
|
|
62
|
+
__APP_ID__: JSON.stringify("education-arm"),
|
|
63
|
+
__APP_BUILD_ID__: JSON.stringify(process.env.BUILD_ID ?? "local"),
|
|
64
|
+
}
|
|
65
|
+
`})}),`
|
|
66
|
+
`,(0,c.jsxs)(t.p,{children:[`Модуль persisted diagnostics использует инфраструктуру `,(0,c.jsx)(t.code,{children:`/query-client`}),`; её compile-time persistence-константы тоже должны быть настроены, если приложение включает соответствующую часть query persistence.`]}),`
|
|
67
|
+
`,(0,c.jsx)(t.h2,{id:`быстрый-старт-для-runtime-ошибок`,children:`Быстрый старт для runtime-ошибок`}),`
|
|
68
|
+
`,(0,c.jsx)(t.h3,{id:`прямой-capture`,children:`Прямой capture`}),`
|
|
69
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`try {
|
|
70
|
+
await runImport();
|
|
71
|
+
} catch (error) {
|
|
72
|
+
const draft = await captureRuntimeErrorReport(error, {
|
|
73
|
+
source: "users-import",
|
|
74
|
+
detail: {
|
|
75
|
+
fileType: selectedFile.type,
|
|
76
|
+
step: "upload"
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
if (draft) {
|
|
81
|
+
await sendDraft(draft);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
throw error;
|
|
85
|
+
}
|
|
86
|
+
`})}),`
|
|
87
|
+
`,(0,c.jsx)(t.h3,{id:`через-независимый-runtime-facade`,children:`Через независимый runtime facade`}),`
|
|
88
|
+
`,(0,c.jsx)(t.p,{children:`Общий код может не знать о QueryClient и delivery. Приложение один раз регистрирует reporter:`}),`
|
|
89
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`setErrorReportRuntimeErrorReporter(async (error, context) => {
|
|
90
|
+
const draft = await captureRuntimeErrorReport(error, context, queryClient);
|
|
91
|
+
|
|
92
|
+
if (draft) {
|
|
93
|
+
await deliverErrorReport(draft);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
`})}),`
|
|
97
|
+
`,(0,c.jsx)(t.p,{children:`После этого любой нижний слой может безопасно вызвать:`}),`
|
|
98
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`await reportRuntimeError(error, {
|
|
99
|
+
source: "document-download",
|
|
100
|
+
detail: { action: "download" }
|
|
101
|
+
});
|
|
102
|
+
`})}),`
|
|
103
|
+
`,(0,c.jsxs)(t.p,{children:[(0,c.jsx)(t.code,{children:`reportRuntimeError`}),` ничего не делает без зарегистрированного reporter и подавляет ошибки самого reporter. Для отключения:`]}),`
|
|
104
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`setErrorReportRuntimeErrorReporter(undefined);
|
|
105
|
+
`})}),`
|
|
106
|
+
`,(0,c.jsx)(t.p,{children:`Одновременно хранится один runtime reporter. Новая регистрация заменяет предыдущую и очищает внутреннее окно runtime-дедупликации.`}),`
|
|
107
|
+
`,(0,c.jsx)(t.h2,{id:`нормализация-ошибки`,children:`Нормализация ошибки`}),`
|
|
108
|
+
`,(0,c.jsx)(t.h3,{id:`createerrorinfoerror`,children:(0,c.jsx)(t.code,{children:`createErrorInfo(error)`})}),`
|
|
109
|
+
`,(0,c.jsx)(t.p,{children:`Любое брошенное значение преобразуется к форме:`}),`
|
|
110
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`type ErrorReportErrorInfo = {
|
|
111
|
+
name: string;
|
|
112
|
+
message: string;
|
|
113
|
+
code?: string;
|
|
114
|
+
stackTrace?: string;
|
|
115
|
+
httpStatus?: number;
|
|
116
|
+
};
|
|
117
|
+
`})}),`
|
|
118
|
+
`,(0,c.jsxs)(t.p,{children:[`Для обычного `,(0,c.jsx)(t.code,{children:`Error`}),` сохраняются `,(0,c.jsx)(t.code,{children:`name`}),`, непустой `,(0,c.jsx)(t.code,{children:`message`}),` и полный `,(0,c.jsx)(t.code,{children:`stack`}),`.`]}),`
|
|
119
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`createErrorInfo(new Error("Не удалось сохранить"));
|
|
120
|
+
// { name: "Error", message: "Не удалось сохранить", stackTrace: "..." }
|
|
121
|
+
`})}),`
|
|
122
|
+
`,(0,c.jsx)(t.p,{children:`Пустое сообщение, пустая строка и строка из пробелов заменяются на «Неизвестная ошибка».`}),`
|
|
123
|
+
`,(0,c.jsxs)(t.p,{children:[`Для plain object читаются `,(0,c.jsx)(t.code,{children:`name`}),`, `,(0,c.jsx)(t.code,{children:`message`}),`, `,(0,c.jsx)(t.code,{children:`stack`}),` и первый из числовых `,(0,c.jsx)(t.code,{children:`status`}),`, `,(0,c.jsx)(t.code,{children:`statusCode`}),`, `,(0,c.jsx)(t.code,{children:`httpStatus`}),`. Другие поля объекта автоматически не включаются.`]}),`
|
|
124
|
+
`,(0,c.jsxs)(t.p,{children:[`Также распознаётся serverFn transport-форма с `,(0,c.jsx)(t.code,{children:`error.appError`}),`: она превращается в `,(0,c.jsx)(t.code,{children:`name: "AppError"`}),`, сохраняет `,(0,c.jsx)(t.code,{children:`message`}),`, `,(0,c.jsx)(t.code,{children:`code`}),` и status.`]}),`
|
|
125
|
+
`,(0,c.jsx)(t.h2,{id:`безопасные-диагностические-значения`,children:`Безопасные диагностические значения`}),`
|
|
126
|
+
`,(0,c.jsx)(t.h3,{id:`creatediagnosticvaluevalue-depth`,children:(0,c.jsx)(t.code,{children:`createDiagnosticValue(value, depth?)`})}),`
|
|
127
|
+
`,(0,c.jsxs)(t.p,{children:[`Преобразует произвольное значение в JSON-совместимое дерево `,(0,c.jsx)(t.code,{children:`ErrorReportSafeValue`}),`.`]}),`
|
|
128
|
+
`,(0,c.jsx)(t.p,{children:`Правила ограничения:`}),`
|
|
129
|
+
`,(0,c.jsxs)(t.ul,{children:[`
|
|
130
|
+
`,(0,c.jsx)(t.li,{children:`максимальная глубина — 4;`}),`
|
|
131
|
+
`,(0,c.jsx)(t.li,{children:`максимум 20 элементов массива;`}),`
|
|
132
|
+
`,(0,c.jsx)(t.li,{children:`максимум 40 ключей объекта;`}),`
|
|
133
|
+
`,(0,c.jsxs)(t.li,{children:[(0,c.jsx)(t.code,{children:`undefined`}),`, function, symbol и усечённая ветка получают специальные объекты `,(0,c.jsx)(t.code,{children:`{ type: ... }`}),`;`]}),`
|
|
134
|
+
`,(0,c.jsxs)(t.li,{children:[(0,c.jsx)(t.code,{children:`bigint`}),` превращается в строку;`]}),`
|
|
135
|
+
`,(0,c.jsxs)(t.li,{children:[(0,c.jsx)(t.code,{children:`Date`}),` — в ISO-строку.`]}),`
|
|
136
|
+
`]}),`
|
|
137
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`createDiagnosticValue({ retry: 2, handler: () => undefined });
|
|
138
|
+
// { retry: 2, handler: { type: "function" } }
|
|
139
|
+
`})}),`
|
|
140
|
+
`,(0,c.jsxs)(t.p,{children:[`Критически важно: функция `,(0,c.jsx)(t.strong,{children:`не скрывает значения по имени ключа`}),`. Поля `,(0,c.jsx)(t.code,{children:`token`}),`, `,(0,c.jsx)(t.code,{children:`password`}),`, `,(0,c.jsx)(t.code,{children:`authorization`}),`, email и другие секреты сохранятся, если их передать. Это ограничитель размера и типа, а не security sanitizer.`]}),`
|
|
141
|
+
`,(0,c.jsx)(t.h3,{id:`sanitizedetaildetail`,children:(0,c.jsx)(t.code,{children:`sanitizeDetail(detail)`})}),`
|
|
142
|
+
`,(0,c.jsxs)(t.p,{children:[`Применяет `,(0,c.jsx)(t.code,{children:`createDiagnosticValue`}),` к первым 40 полям объекта. Для `,(0,c.jsx)(t.code,{children:`undefined`}),` или пустого объекта возвращает `,(0,c.jsx)(t.code,{children:`undefined`}),`.`]}),`
|
|
143
|
+
`,(0,c.jsx)(t.p,{children:`Передавайте только заранее отобранные технические данные:`}),`
|
|
144
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`sanitizeDetail({
|
|
145
|
+
operation: "save-order",
|
|
146
|
+
entitySet: "Orders",
|
|
147
|
+
rowCount: rows.length
|
|
148
|
+
});
|
|
149
|
+
`})}),`
|
|
150
|
+
`,(0,c.jsx)(t.p,{children:`Не передавайте request body, access token, cookie, персональные поля и полные backend responses.`}),`
|
|
151
|
+
`,(0,c.jsx)(t.h3,{id:`createdatashapevalue-depth`,children:(0,c.jsx)(t.code,{children:`createDataShape(value, depth?)`})}),`
|
|
152
|
+
`,(0,c.jsx)(t.p,{children:`Описывает структуру данных без leaf-значений:`}),`
|
|
153
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`createDataShape({ rows: [{ id: "42", amount: 100 }] });
|
|
154
|
+
// объект с keys/shape, массивом length и shape первых трёх элементов
|
|
155
|
+
`})}),`
|
|
156
|
+
`,(0,c.jsx)(t.p,{children:`Для массива сохраняются длина и формы первых трёх элементов. Для объекта — первые 40 ключей и их формы. Именно эта функция используется для query data, чтобы не копировать содержимое кэша.`}),`
|
|
157
|
+
`,(0,c.jsx)(t.h2,{id:`breadcrumbs`,children:`Breadcrumbs`}),`
|
|
158
|
+
`,(0,c.jsx)(t.p,{children:`Breadcrumb — короткая запись о событии перед ошибкой.`}),`
|
|
159
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`type ErrorReportBreadcrumb = {
|
|
160
|
+
utc: string;
|
|
161
|
+
type: "route" | "click" | "visibility" | "query-error" | "mutation-error" | "runtime-error";
|
|
162
|
+
routeId?: string;
|
|
163
|
+
appId?: string;
|
|
164
|
+
viewId?: string;
|
|
165
|
+
target?: string;
|
|
166
|
+
detail?: Record<string, ErrorReportSafeValue>;
|
|
167
|
+
};
|
|
168
|
+
`})}),`
|
|
169
|
+
`,(0,c.jsx)(t.h3,{id:`ручное-добавление`,children:`Ручное добавление`}),`
|
|
170
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`addErrorReportBreadcrumb({
|
|
171
|
+
type: "route",
|
|
172
|
+
routeId: "/orders/$id",
|
|
173
|
+
detail: sanitizeDetail({ orderId: "42" })
|
|
174
|
+
});
|
|
175
|
+
`})}),`
|
|
176
|
+
`,(0,c.jsxs)(t.p,{children:[`Если `,(0,c.jsx)(t.code,{children:`utc`}),` отсутствует, используется текущий ISO timestamp. В памяти остаются последние 80 breadcrumbs.`]}),`
|
|
177
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`getErrorReportBreadcrumbs();
|
|
178
|
+
clearErrorReportBreadcrumbs();
|
|
179
|
+
`})}),`
|
|
180
|
+
`,(0,c.jsx)(t.p,{children:`Возвращаемый массив является текущим внутренним массивом, а не глубокой копией. Считайте его readonly и не меняйте элементы вручную.`}),`
|
|
181
|
+
`,(0,c.jsx)(t.h3,{id:`автоматические-browser-breadcrumbs`,children:`Автоматические browser breadcrumbs`}),`
|
|
182
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`const uninstallBreadcrumbs = installErrorReportBrowserBreadcrumbs();
|
|
183
|
+
|
|
184
|
+
// При демонтаже client shell:
|
|
185
|
+
uninstallBreadcrumbs();
|
|
186
|
+
`})}),`
|
|
187
|
+
`,(0,c.jsx)(t.p,{children:`Установщик слушает:`}),`
|
|
188
|
+
`,(0,c.jsxs)(t.ul,{children:[`
|
|
189
|
+
`,(0,c.jsx)(t.li,{children:`click в capture phase;`}),`
|
|
190
|
+
`,(0,c.jsxs)(t.li,{children:[(0,c.jsx)(t.code,{children:`document.visibilitychange`}),`.`]}),`
|
|
191
|
+
`]}),`
|
|
192
|
+
`,(0,c.jsx)(t.p,{children:`Для click сохраняются координаты/модификаторы и ограниченное описание meaningful target: tag, стабильные атрибуты, короткий текст и цепочка родителей. Глубина DOM-цепочки ограничена 20, текст — 80 символами, атрибут — 120.`}),`
|
|
193
|
+
`,(0,c.jsxs)(t.p,{children:[`Код не читает `,(0,c.jsx)(t.code,{children:`input.value`}),` и не копирует CSS class list, но текст/ARIA/title/data-атрибуты тоже могут содержать чувствительные данные. Не помещайте секреты в DOM-атрибуты и UI-текст.`]}),`
|
|
194
|
+
`,(0,c.jsx)(t.p,{children:`На сервере установщик возвращает пустую cleanup-функцию.`}),`
|
|
195
|
+
`,(0,c.jsx)(t.h2,{id:`диагностика-tanstack-query`,children:`Диагностика TanStack Query`}),`
|
|
196
|
+
`,(0,c.jsx)(t.h3,{id:`collectquerydiagnosticsquery`,children:(0,c.jsx)(t.code,{children:`collectQueryDiagnostics(query)`})}),`
|
|
197
|
+
`,(0,c.jsx)(t.p,{children:`Собирает:`}),`
|
|
198
|
+
`,(0,c.jsxs)(t.ul,{children:[`
|
|
199
|
+
`,(0,c.jsxs)(t.li,{children:[(0,c.jsx)(t.code,{children:`queryHash`}),` и диагностическое представление `,(0,c.jsx)(t.code,{children:`queryKey`}),`;`]}),`
|
|
200
|
+
`,(0,c.jsx)(t.li,{children:`status/fetchStatus;`}),`
|
|
201
|
+
`,(0,c.jsx)(t.li,{children:`timestamps обновления data/error;`}),`
|
|
202
|
+
`,(0,c.jsx)(t.li,{children:`failure count, invalidation и observer count;`}),`
|
|
203
|
+
`,(0,c.jsx)(t.li,{children:`meta;`}),`
|
|
204
|
+
`,(0,c.jsxs)(t.li,{children:[(0,c.jsx)(t.code,{children:`dataShape`}),` вместо data;`]}),`
|
|
205
|
+
`,(0,c.jsx)(t.li,{children:`нормализованную query error.`}),`
|
|
206
|
+
`]}),`
|
|
207
|
+
`,(0,c.jsxs)(t.p,{children:[`Значения `,(0,c.jsx)(t.code,{children:`queryKey`}),` и `,(0,c.jsx)(t.code,{children:`meta`}),` сохраняются. Если туда попал token или персональный идентификатор, он попадёт в отчёт. Проектируйте query keys как диагностически безопасный контракт.`]}),`
|
|
208
|
+
`,(0,c.jsx)(t.h3,{id:`collectmutationdiagnosticsmutation`,children:(0,c.jsx)(t.code,{children:`collectMutationDiagnostics(mutation)`})}),`
|
|
209
|
+
`,(0,c.jsx)(t.p,{children:`Собирает mutation key, status, failure count, submitted timestamp, meta и error. Mutation variables/data не копируются.`}),`
|
|
210
|
+
`,(0,c.jsx)(t.h3,{id:`collectqueryclientdiagnosticsqueryclient`,children:(0,c.jsx)(t.code,{children:`collectQueryClientDiagnostics(queryClient)`})}),`
|
|
211
|
+
`,(0,c.jsx)(t.p,{children:`Возвращает последние 40 query и последние 40 mutations из соответствующих cache. Это синхронный snapshot текущего QueryClient.`}),`
|
|
212
|
+
`,(0,c.jsx)(t.h3,{id:`collectpersistedquerydiagnostics`,children:(0,c.jsx)(t.code,{children:`collectPersistedQueryDiagnostics()`})}),`
|
|
213
|
+
`,(0,c.jsxs)(t.p,{children:[`Асинхронно читает IndexedDB persistence из `,(0,c.jsx)(t.code,{children:`/query-client`}),` и возвращает максимум 40 записей.`]}),`
|
|
214
|
+
`,(0,c.jsxs)(t.p,{children:[`Сохраняются storage key, buster, query hash/key, statuses, timestamps, failure count и error. `,(0,c.jsx)(t.code,{children:`state.data`}),` намеренно исключён полностью.`]}),`
|
|
215
|
+
`,(0,c.jsx)(t.p,{children:`Если IndexedDB/persistence недоступны или чтение бросает ошибку, возвращается пустой массив — сбор отчёта не падает.`}),`
|
|
216
|
+
`,(0,c.jsx)(t.h2,{id:`capture-query-ошибки`,children:`Capture query-ошибки`}),`
|
|
217
|
+
`,(0,c.jsx)(t.h3,{id:`capturequeryerrorreporterror-query-queryclient-context`,children:(0,c.jsx)(t.code,{children:`captureQueryErrorReport(error, query, queryClient, context?)`})}),`
|
|
218
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`const draft = await captureQueryErrorReport(error, query, queryClient, {
|
|
219
|
+
source: "orders-list",
|
|
220
|
+
detail: { routeId: "/orders" }
|
|
221
|
+
});
|
|
222
|
+
`})}),`
|
|
223
|
+
`,(0,c.jsx)(t.p,{children:`Функция:`}),`
|
|
224
|
+
`,(0,c.jsxs)(t.ol,{children:[`
|
|
225
|
+
`,(0,c.jsxs)(t.li,{children:[`подавляет отложенный transport-report для того же экземпляра `,(0,c.jsx)(t.code,{children:`Error`}),`;`]}),`
|
|
226
|
+
`,(0,c.jsxs)(t.li,{children:[`добавляет breadcrumb `,(0,c.jsx)(t.code,{children:`query-error`}),`;`]}),`
|
|
227
|
+
`,(0,c.jsx)(t.li,{children:`параллельно читает persisted diagnostics и QueryClient snapshot;`}),`
|
|
228
|
+
`,(0,c.jsx)(t.li,{children:`собирает подробности конкретной query;`}),`
|
|
229
|
+
`,(0,c.jsxs)(t.li,{children:[`создаёт draft категории `,(0,c.jsx)(t.code,{children:`query`}),`.`]}),`
|
|
230
|
+
`]}),`
|
|
231
|
+
`,(0,c.jsxs)(t.p,{children:[`Возвращает `,(0,c.jsx)(t.code,{children:`ErrorReportDraft | undefined`}),`. В development/SSR будет `,(0,c.jsx)(t.code,{children:`undefined`}),`.`]}),`
|
|
232
|
+
`,(0,c.jsxs)(t.p,{children:[(0,c.jsx)(t.code,{children:`context.errorInfo`}),` позволяет передать уже нормализованную ошибку, `,(0,c.jsx)(t.code,{children:`context.queryKey`}),` — переопределить breadcrumb key, `,(0,c.jsx)(t.code,{children:`context.detail`}),` — добавить контролируемый context.`]}),`
|
|
233
|
+
`,(0,c.jsxs)(t.p,{children:[`Параметр `,(0,c.jsx)(t.code,{children:`query`}),` — реальный объект TanStack Query cache, а не `,(0,c.jsx)(t.code,{children:`UseQueryResult`}),` и не query options.`]}),`
|
|
234
|
+
`,(0,c.jsx)(t.h2,{id:`capture-mutation-ошибки`,children:`Capture mutation-ошибки`}),`
|
|
235
|
+
`,(0,c.jsx)(t.h3,{id:`capturemutationerrorreporterror-mutation-queryclient-context`,children:(0,c.jsx)(t.code,{children:`captureMutationErrorReport(error, mutation, queryClient, context?)`})}),`
|
|
236
|
+
`,(0,c.jsx)(t.p,{children:`Работает аналогично query capture: подавляет дублирующий transport-report, добавляет mutation breadcrumb и собирает QueryClient/persistence snapshot.`}),`
|
|
237
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`const draft = await captureMutationErrorReport(error, mutation, queryClient, { source: "save-order", detail: { form: "order-edit" } });
|
|
238
|
+
`})}),`
|
|
239
|
+
`,(0,c.jsxs)(t.p,{children:[`Текущая реализация включает `,(0,c.jsx)(t.code,{children:`detail`}),` в breadcrumb, но не переносит его в `,(0,c.jsx)(t.code,{children:`payload.context`}),` mutation draft. Если этот контекст критичен для доставки, добавьте безопасные данные в app-level envelope либо используйте явную согласованную модель до capture.`]}),`
|
|
240
|
+
`,(0,c.jsx)(t.h2,{id:`capture-runtimereact-ошибки`,children:`Capture runtime/React-ошибки`}),`
|
|
241
|
+
`,(0,c.jsx)(t.h3,{id:`captureruntimeerrorreporterror-context-queryclient`,children:(0,c.jsx)(t.code,{children:`captureRuntimeErrorReport(error, context?, queryClient?)`})}),`
|
|
242
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`const draft = await captureRuntimeErrorReport(
|
|
243
|
+
error,
|
|
244
|
+
{
|
|
245
|
+
category: "react",
|
|
246
|
+
source: "error-boundary",
|
|
247
|
+
componentStack: info.componentStack,
|
|
248
|
+
detail: { routeId }
|
|
249
|
+
},
|
|
250
|
+
queryClient
|
|
251
|
+
);
|
|
252
|
+
`})}),`
|
|
253
|
+
`,(0,c.jsxs)(t.p,{children:[`Без `,(0,c.jsx)(t.code,{children:`queryClient`}),` отчёт создаётся без query/persisted diagnostics. Это полезно для низкоуровневого runtime кода. С QueryClient добавляется общий snapshot.`]}),`
|
|
254
|
+
`,(0,c.jsxs)(t.p,{children:[`По умолчанию category/source — `,(0,c.jsx)(t.code,{children:`runtime`}),`. `,(0,c.jsx)(t.code,{children:`componentStack`}),` записывается в секцию `,(0,c.jsx)(t.code,{children:`react`}),`.`]}),`
|
|
255
|
+
`,(0,c.jsx)(t.p,{children:`Одинаковые runtime/React capture в браузере объединяются примерно на 60 секунд по fingerprint ошибки, source, path, component stack и detail. Параллельные вызовы получают одну Promise/draft. Это защищает от лавины одинаковых отчётов. После отклонения capture внутренняя запись удаляется.`}),`
|
|
256
|
+
`,(0,c.jsx)(t.h2,{id:`draft-и-payload`,children:`Draft и payload`}),`
|
|
257
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`type ErrorReportStatus = "pending" | "sending" | "sent" | "failed";
|
|
258
|
+
|
|
259
|
+
type ErrorReportDraft = {
|
|
260
|
+
reportId: string;
|
|
261
|
+
sessionId: string;
|
|
262
|
+
createdUtc: string;
|
|
263
|
+
category: ErrorReportCategory;
|
|
264
|
+
status: ErrorReportStatus;
|
|
265
|
+
sentUtc?: string;
|
|
266
|
+
failedReason?: string;
|
|
267
|
+
payload: ErrorReportPayload;
|
|
268
|
+
};
|
|
269
|
+
`})}),`
|
|
270
|
+
`,(0,c.jsxs)(t.p,{children:[(0,c.jsx)(t.code,{children:`reportId`}),` — UUID отдельного отчёта. `,(0,c.jsx)(t.code,{children:`sessionId`}),` стабилен в текущем `,(0,c.jsx)(t.code,{children:`sessionStorage`}),`. `,(0,c.jsx)(t.code,{children:`createdUtc`}),` формируется как OData datetime UTC.`]}),`
|
|
271
|
+
`,(0,c.jsx)(t.p,{children:`Payload содержит category/source/error, build environment, client, location, viewport, breadcrumbs и optional секции query/mutation/react/context.`}),`
|
|
272
|
+
`,(0,c.jsx)(t.h3,{id:`хранение`,children:`Хранение`}),`
|
|
273
|
+
`,(0,c.jsxs)(t.p,{children:[`Drafts сохраняются под ключом `,(0,c.jsx)(t.code,{children:"${__APP_ID__}.errorReport.drafts.v1"}),`. В одной вкладке остаются последние 10 элементов. Старые удаляются с начала массива.`]}),`
|
|
274
|
+
`,(0,c.jsx)(t.p,{children:`Storage errors и некорректный JSON подавляются. При переполнении sessionStorage текущее in-memory состояние обновится, но запись на диск может не сохраниться.`}),`
|
|
275
|
+
`,(0,c.jsx)(t.p,{children:`Модуль загружает drafts при первом импорте. Это модульное состояние, общее для всех consumers одного bundle.`}),`
|
|
276
|
+
`,(0,c.jsxs)(t.h2,{id:`низкоуровневый-captureerrorreportdraftargs`,children:[`Низкоуровневый `,(0,c.jsx)(t.code,{children:`captureErrorReportDraft(args)`})]}),`
|
|
277
|
+
`,(0,c.jsx)(t.p,{children:`Используйте, когда все diagnostic sections уже подготовлены вручную:`}),`
|
|
278
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`const draft = captureErrorReportDraft({
|
|
279
|
+
category: "runtime",
|
|
280
|
+
source: "custom-engine",
|
|
281
|
+
error: createErrorInfo(error),
|
|
282
|
+
context: sanitizeDetail({ stage: "compile" })
|
|
283
|
+
});
|
|
284
|
+
`})}),`
|
|
285
|
+
`,(0,c.jsx)(t.p,{children:`Функция добавит report/session IDs, environment, client/location/viewport и текущие breadcrumbs. Она синхронная и не собирает QueryClient автоматически.`}),`
|
|
286
|
+
`,(0,c.jsx)(t.h2,{id:`чтение-и-обновление-drafts`,children:`Чтение и обновление drafts`}),`
|
|
287
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`const drafts = getErrorReportDrafts();
|
|
288
|
+
const draft = getErrorReportDraft(reportId);
|
|
289
|
+
`})}),`
|
|
290
|
+
`,(0,c.jsxs)(t.p,{children:[`Возвращаются ссылки из внутреннего массива. Считайте их readonly; для lifecycle используйте `,(0,c.jsx)(t.code,{children:`updateErrorReportDraft`}),`.`]}),`
|
|
291
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`updateErrorReportDraft(reportId, { status: "sending" });
|
|
292
|
+
|
|
293
|
+
try {
|
|
294
|
+
await api.sendErrorReport(draft.payload);
|
|
295
|
+
updateErrorReportDraft(reportId, {
|
|
296
|
+
status: "sent",
|
|
297
|
+
sentUtc: new Date().toISOString(),
|
|
298
|
+
failedReason: undefined
|
|
299
|
+
});
|
|
300
|
+
} catch (error) {
|
|
301
|
+
updateErrorReportDraft(reportId, {
|
|
302
|
+
status: "failed",
|
|
303
|
+
failedReason: createErrorInfo(error).message
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
`})}),`
|
|
307
|
+
`,(0,c.jsxs)(t.p,{children:[`Для неизвестного ID update возвращает `,(0,c.jsx)(t.code,{children:`undefined`}),`. Обновление поверхностное и принимает `,(0,c.jsx)(t.code,{children:`Partial<ErrorReportDraft>`}),`: библиотека не проверяет разрешённые переходы статусов. App delivery обязан не менять `,(0,c.jsx)(t.code,{children:`reportId`}),`, payload и другие identity-поля без необходимости.`]}),`
|
|
308
|
+
`,(0,c.jsx)(t.h2,{id:`environment-api`,children:`Environment API`}),`
|
|
309
|
+
`,(0,c.jsx)(t.h3,{id:`geterrorreportenvironment`,children:(0,c.jsx)(t.code,{children:`getErrorReportEnvironment()`})}),`
|
|
310
|
+
`,(0,c.jsxs)(t.p,{children:[`Возвращает mode из `,(0,c.jsx)(t.code,{children:`__DEV__`}),` и build ID.`]}),`
|
|
311
|
+
`,(0,c.jsx)(t.h3,{id:`geterrorreportclientenvironment`,children:(0,c.jsx)(t.code,{children:`getErrorReportClientEnvironment()`})}),`
|
|
312
|
+
`,(0,c.jsxs)(t.p,{children:[`В браузере возвращает user agent, language и timezone. На сервере — `,(0,c.jsx)(t.code,{children:`undefined`}),`.`]}),`
|
|
313
|
+
`,(0,c.jsx)(t.p,{children:`Эти поля могут считаться персональными/идентифицирующими данными в политике организации. Согласуйте срок хранения и доступ к отчётам.`}),`
|
|
314
|
+
`,(0,c.jsx)(t.h2,{id:`transport-reporter`,children:`Transport reporter`}),`
|
|
315
|
+
`,(0,c.jsx)(t.p,{children:`Transport-слой может сообщить об ошибке parsing/fetch, не зная о QueryClient и UI.`}),`
|
|
316
|
+
`,(0,c.jsx)(t.h3,{id:`регистрация`,children:`Регистрация`}),`
|
|
317
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`setErrorReportTransportErrorReporter(async (error, context) => {
|
|
318
|
+
const draft = await captureRuntimeErrorReport(
|
|
319
|
+
error,
|
|
320
|
+
{
|
|
321
|
+
source: context.source,
|
|
322
|
+
detail: context
|
|
323
|
+
},
|
|
324
|
+
queryClient
|
|
325
|
+
);
|
|
326
|
+
|
|
327
|
+
if (draft) {
|
|
328
|
+
await deliverErrorReport(draft);
|
|
329
|
+
}
|
|
330
|
+
});
|
|
331
|
+
`})}),`
|
|
332
|
+
`,(0,c.jsxs)(t.p,{children:[`Для отключения передайте `,(0,c.jsx)(t.code,{children:`undefined`}),`. Регистрация очищает недавние transport keys.`]}),`
|
|
333
|
+
`,(0,c.jsx)(t.h3,{id:`reporttransporterrorerror-context`,children:(0,c.jsx)(t.code,{children:`reportTransportError(error, context)`})}),`
|
|
334
|
+
`,(0,c.jsxs)(t.p,{children:[`Context имеет source `,(0,c.jsx)(t.code,{children:`fetch.parseResponse`}),` или `,(0,c.jsx)(t.code,{children:`fetch.buildHttpError`}),` и может содержать URL, method, SAP client, status/content type, redirect/response type и безопасное summary HTML-response.`]}),`
|
|
335
|
+
`,(0,c.jsxs)(t.p,{children:[`Вызов планирует reporter через 250 мс. Задержка позволяет TanStack Query перехватить тот же `,(0,c.jsx)(t.code,{children:`Error`}),` и создать более полезный query/mutation report.`]}),`
|
|
336
|
+
`,(0,c.jsx)(t.h3,{id:`подавление-дубля`,children:`Подавление дубля`}),`
|
|
337
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`isTransportErrorReportScheduled(error);
|
|
338
|
+
suppressTransportErrorReport(error);
|
|
339
|
+
`})}),`
|
|
340
|
+
`,(0,c.jsxs)(t.p,{children:[`Capture query/mutation вызывает suppression автоматически. Проверка работает только для того же экземпляра `,(0,c.jsx)(t.code,{children:`Error`}),`, потому что внутри используются WeakSet.`]}),`
|
|
341
|
+
`,(0,c.jsx)(t.p,{children:`Transport reports дополнительно дедуплицируются на 60 секунд по source, method, status и URL. Хранится ограниченное число недавних ключей.`}),`
|
|
342
|
+
`,(0,c.jsx)(t.p,{children:`Если reporter отсутствует, подавлен, недавно уже сработал или сам бросил ошибку, основной transport-сценарий не ломается.`}),`
|
|
343
|
+
`,(0,c.jsx)(t.h2,{id:`рекомендуемая-app-level-интеграция`,children:`Рекомендуемая app-level интеграция`}),`
|
|
344
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`export function installErrorReporting(queryClient: QueryClient) {
|
|
345
|
+
const uninstallBreadcrumbs = installErrorReportBrowserBreadcrumbs();
|
|
346
|
+
|
|
347
|
+
setErrorReportRuntimeErrorReporter(async (error, context) => {
|
|
348
|
+
const draft = await captureRuntimeErrorReport(error, context, queryClient);
|
|
349
|
+
if (draft) await deliverDraft(draft);
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
setErrorReportTransportErrorReporter(async (error, context) => {
|
|
353
|
+
const draft = await captureRuntimeErrorReport(
|
|
354
|
+
error,
|
|
355
|
+
{ source: context.source, detail: pickSafeTransportFields(context) },
|
|
356
|
+
queryClient
|
|
357
|
+
);
|
|
358
|
+
if (draft) await deliverDraft(draft);
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
return () => {
|
|
362
|
+
uninstallBreadcrumbs();
|
|
363
|
+
setErrorReportRuntimeErrorReporter(undefined);
|
|
364
|
+
setErrorReportTransportErrorReporter(undefined);
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
`})}),`
|
|
368
|
+
`,(0,c.jsxs)(t.p,{children:[`Создавайте lifecycle один раз в client shell. Функция `,(0,c.jsx)(t.code,{children:`pickSafeTransportFields`}),` — ответственность приложения и должна явно разрешать поля, а не копировать произвольный объект.`]}),`
|
|
369
|
+
`,(0,c.jsx)(t.h2,{id:`безопасность-и-приватность`,children:`Безопасность и приватность`}),`
|
|
370
|
+
`,(0,c.jsx)(t.p,{children:`Перед включением production delivery обязательно определите data policy.`}),`
|
|
371
|
+
`,(0,c.jsx)(t.h3,{id:`что-намеренно-не-сохраняется`,children:`Что намеренно не сохраняется`}),`
|
|
372
|
+
`,(0,c.jsxs)(t.ul,{children:[`
|
|
373
|
+
`,(0,c.jsxs)(t.li,{children:[`полное `,(0,c.jsx)(t.code,{children:`query.state.data`}),`;`]}),`
|
|
374
|
+
`,(0,c.jsxs)(t.li,{children:[`persisted `,(0,c.jsx)(t.code,{children:`state.data`}),`;`]}),`
|
|
375
|
+
`,(0,c.jsx)(t.li,{children:`mutation variables;`}),`
|
|
376
|
+
`,(0,c.jsx)(t.li,{children:`значения input при автоматическом click breadcrumb;`}),`
|
|
377
|
+
`,(0,c.jsx)(t.li,{children:`тела transport-запросов.`}),`
|
|
378
|
+
`]}),`
|
|
379
|
+
`,(0,c.jsx)(t.h3,{id:`что-всё-ещё-может-содержать-данные`,children:`Что всё ещё может содержать данные`}),`
|
|
380
|
+
`,(0,c.jsxs)(t.ul,{children:[`
|
|
381
|
+
`,(0,c.jsx)(t.li,{children:`queryKey и mutationKey;`}),`
|
|
382
|
+
`,(0,c.jsx)(t.li,{children:`query/mutation meta;`}),`
|
|
383
|
+
`,(0,c.jsxs)(t.li,{children:[(0,c.jsx)(t.code,{children:`context.detail`}),`;`]}),`
|
|
384
|
+
`,(0,c.jsx)(t.li,{children:`URL и pathname;`}),`
|
|
385
|
+
`,(0,c.jsx)(t.li,{children:`error message/stack;`}),`
|
|
386
|
+
`,(0,c.jsx)(t.li,{children:`UI text, ARIA/title/data attributes breadcrumbs;`}),`
|
|
387
|
+
`,(0,c.jsx)(t.li,{children:`user agent, language, timezone;`}),`
|
|
388
|
+
`,(0,c.jsx)(t.li,{children:`имена persisted storage keys.`}),`
|
|
389
|
+
`]}),`
|
|
390
|
+
`,(0,c.jsx)(t.p,{children:`Поэтому:`}),`
|
|
391
|
+
`,(0,c.jsxs)(t.ol,{children:[`
|
|
392
|
+
`,(0,c.jsx)(t.li,{children:`не помещайте секреты в query keys/meta;`}),`
|
|
393
|
+
`,(0,c.jsx)(t.li,{children:`собирайте detail по allow-list;`}),`
|
|
394
|
+
`,(0,c.jsx)(t.li,{children:`очищайте URL от token/query secrets до передачи в custom context;`}),`
|
|
395
|
+
`,(0,c.jsx)(t.li,{children:`защищайте endpoint доставки;`}),`
|
|
396
|
+
`,(0,c.jsx)(t.li,{children:`задайте срок хранения и права доступа;`}),`
|
|
397
|
+
`,(0,c.jsx)(t.li,{children:`при необходимости запрашивайте согласие пользователя;`}),`
|
|
398
|
+
`,(0,c.jsx)(t.li,{children:`не показывайте необработанный stack trace всем пользователям.`}),`
|
|
399
|
+
`]}),`
|
|
400
|
+
`,(0,c.jsx)(t.h2,{id:`частые-ошибки`,children:`Частые ошибки`}),`
|
|
401
|
+
`,(0,c.jsx)(t.h3,{id:`ожидать-автоматическую-отправку`,children:`Ожидать автоматическую отправку`}),`
|
|
402
|
+
`,(0,c.jsx)(t.p,{children:`Capture только создаёт draft. Delivery нужно явно подключить.`}),`
|
|
403
|
+
`,(0,c.jsxs)(t.h3,{id:`использовать-creatediagnosticvalue-как-redactor`,children:[`Использовать `,(0,c.jsx)(t.code,{children:`createDiagnosticValue`}),` как redactor`]}),`
|
|
404
|
+
`,(0,c.jsx)(t.p,{children:`Он ограничивает размер, но сохраняет значения независимо от имени поля.`}),`
|
|
405
|
+
`,(0,c.jsx)(t.h3,{id:`вызывать-production-capture-в-development-и-ждать-draft`,children:`Вызывать production capture в development и ждать draft`}),`
|
|
406
|
+
`,(0,c.jsxs)(t.p,{children:[`По контракту вернётся `,(0,c.jsx)(t.code,{children:`undefined`}),`.`]}),`
|
|
407
|
+
`,(0,c.jsx)(t.h3,{id:`не-очищать-глобальные-reporters`,children:`Не очищать глобальные reporters`}),`
|
|
408
|
+
`,(0,c.jsx)(t.p,{children:`При hot reload, тестах или размонтировании shell снимайте bindings, чтобы старый QueryClient/delivery не оставался в closure.`}),`
|
|
409
|
+
`,(0,c.jsxs)(t.h3,{id:`мутировать-результат-geterrorreportdrafts`,children:[`Мутировать результат `,(0,c.jsx)(t.code,{children:`getErrorReportDrafts()`})]}),`
|
|
410
|
+
`,(0,c.jsxs)(t.p,{children:[`Используйте `,(0,c.jsx)(t.code,{children:`updateErrorReportDraft`}),`; прямое изменение обходит сохранение в sessionStorage.`]}),`
|
|
411
|
+
`,(0,c.jsxs)(t.h3,{id:`передавать-usequeryresult-вместо-cache-query`,children:[`Передавать `,(0,c.jsx)(t.code,{children:`UseQueryResult`}),` вместо cache Query`]}),`
|
|
412
|
+
`,(0,c.jsxs)(t.p,{children:[(0,c.jsx)(t.code,{children:`captureQueryErrorReport`}),` нужен объект Query, обычно доступный внутри QueryCache callbacks/instrumentation.`]}),`
|
|
413
|
+
`,(0,c.jsx)(t.h3,{id:`создать-цикл-отчётов`,children:`Создать цикл отчётов`}),`
|
|
414
|
+
`,(0,c.jsx)(t.p,{children:`Ошибка endpoint доставки не должна снова проходить через тот же автоматический transport reporter. Пометьте/исключите delivery transport или используйте отдельный канал.`}),`
|
|
415
|
+
`,(0,c.jsx)(t.h2,{id:`краткая-карта-api`,children:`Краткая карта API`}),`
|
|
416
|
+
`,(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:`Capture`}),(0,c.jsxs)(t.td,{children:[(0,c.jsx)(t.code,{children:`captureQueryErrorReport`}),`, `,(0,c.jsx)(t.code,{children:`captureMutationErrorReport`}),`, `,(0,c.jsx)(t.code,{children:`captureRuntimeErrorReport`}),`, `,(0,c.jsx)(t.code,{children:`captureErrorReportDraft`})]})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:`Errors`}),(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`createErrorInfo`})})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:`Safe values`}),(0,c.jsxs)(t.td,{children:[(0,c.jsx)(t.code,{children:`createDiagnosticValue`}),`, `,(0,c.jsx)(t.code,{children:`createDataShape`}),`, `,(0,c.jsx)(t.code,{children:`sanitizeDetail`})]})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:`Breadcrumbs`}),(0,c.jsxs)(t.td,{children:[(0,c.jsx)(t.code,{children:`addErrorReportBreadcrumb`}),`, `,(0,c.jsx)(t.code,{children:`getErrorReportBreadcrumbs`}),`, `,(0,c.jsx)(t.code,{children:`clearErrorReportBreadcrumbs`}),`, `,(0,c.jsx)(t.code,{children:`installErrorReportBrowserBreadcrumbs`})]})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:`Diagnostics`}),(0,c.jsxs)(t.td,{children:[(0,c.jsx)(t.code,{children:`collectQueryDiagnostics`}),`, `,(0,c.jsx)(t.code,{children:`collectMutationDiagnostics`}),`, `,(0,c.jsx)(t.code,{children:`collectQueryClientDiagnostics`}),`, `,(0,c.jsx)(t.code,{children:`collectPersistedQueryDiagnostics`})]})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:`Drafts`}),(0,c.jsxs)(t.td,{children:[(0,c.jsx)(t.code,{children:`getErrorReportDraft`}),`, `,(0,c.jsx)(t.code,{children:`getErrorReportDrafts`}),`, `,(0,c.jsx)(t.code,{children:`updateErrorReportDraft`})]})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:`Environment`}),(0,c.jsxs)(t.td,{children:[(0,c.jsx)(t.code,{children:`isErrorReportingEnabled`}),`, `,(0,c.jsx)(t.code,{children:`getErrorReportEnvironment`}),`, `,(0,c.jsx)(t.code,{children:`getErrorReportClientEnvironment`})]})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:`Runtime facade`}),(0,c.jsxs)(t.td,{children:[(0,c.jsx)(t.code,{children:`setErrorReportRuntimeErrorReporter`}),`, `,(0,c.jsx)(t.code,{children:`reportRuntimeError`})]})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:`Transport facade`}),(0,c.jsxs)(t.td,{children:[(0,c.jsx)(t.code,{children:`setErrorReportTransportErrorReporter`}),`, `,(0,c.jsx)(t.code,{children:`reportTransportError`}),`, `,(0,c.jsx)(t.code,{children:`isTransportErrorReportScheduled`}),`, `,(0,c.jsx)(t.code,{children:`suppressTransportErrorReport`})]})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:`Contracts`}),(0,c.jsxs)(t.td,{children:[(0,c.jsx)(t.code,{children:`ErrorReportDraft`}),`, `,(0,c.jsx)(t.code,{children:`ErrorReportPayload`}),`, contexts, diagnostics и transport types`]})]})]})]})]})}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};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{n as e}from"./rolldown-runtime-DkW27tQK.js";import{n as t}from"./iframe-
|
|
1
|
+
import{n as e}from"./rolldown-runtime-DkW27tQK.js";import{n as t}from"./iframe-o7sH2IXC.js";import{i as n,r}from"./react-Bl2r1tuC.js";import{l as i,m as a}from"./blocks-BY40djCc.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/Formatters/Обзор`}),`
|
|
2
2
|
`,(0,c.jsx)(t.h1,{id:`ryuzaki13react-foundation-libformatters`,children:(0,c.jsx)(t.code,{children:`@ryuzaki13/react-foundation-lib/formatters`})}),`
|
|
3
3
|
`,(0,c.jsxs)(t.p,{children:[(0,c.jsx)(t.code,{children:`formatters`}),` — большой модуль подготовки значений для интерфейса и transport-контрактов. Он работает с датами, числами, строками, boolean/ABAP-флагами, ФИО, российскими телефонами, ведущими нулями и семантическими состояниями. Для таблиц модуль также предоставляет конфигурируемый formatter pipeline и row-based формулы.`]}),`
|
|
4
4
|
`,(0,c.jsx)(t.p,{children:`Документация разделена по предметным областям, чтобы разработчику не приходилось читать один огромный файл. Этот README объясняет общие правила, помогает выбрать API и подробно описывает небольшие helpers верхнего уровня.`}),`
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import{n as e}from"./rolldown-runtime-DkW27tQK.js";import{n as t}from"./iframe-o7sH2IXC.js";import{i as n,r}from"./react-Bl2r1tuC.js";import{l as i,m as a}from"./blocks-BY40djCc.js";function o(e){let t={code:`code`,h1:`h1`,h2:`h2`,li:`li`,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/Data/Presets`}),`
|
|
2
|
+
`,(0,c.jsxs)(t.h1,{id:`общие-preset-helpers-через-ryuzaki13react-foundation-libpresets`,children:[`Общие preset helpers через `,(0,c.jsx)(t.code,{children:`@ryuzaki13/react-foundation-lib/presets`})]}),`
|
|
3
|
+
`,(0,c.jsx)(t.p,{children:`Модуль проверяет восстановленные preset ids, сопоставляет их с option objects и ищет одну option по id.`}),`
|
|
4
|
+
`,(0,c.jsx)(t.h2,{id:`установка-и-импорт`,children:`Установка и импорт`}),`
|
|
5
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`import { getPresetOption, normalizePresetIds, resolvePresetOptionsByIds } from "@ryuzaki13/react-foundation-lib/presets";
|
|
6
|
+
|
|
7
|
+
import type { PresetOption } from "@ryuzaki13/react-foundation-lib/presets";
|
|
8
|
+
`})}),`
|
|
9
|
+
`,(0,c.jsx)(t.p,{children:`Модуль не зависит от React/browser APIs.`}),`
|
|
10
|
+
`,(0,c.jsx)(t.h2,{id:`базовый-контракт`,children:`Базовый контракт`}),`
|
|
11
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`type PresetOption<TId extends string = string> = {
|
|
12
|
+
id: TId;
|
|
13
|
+
label: string;
|
|
14
|
+
};
|
|
15
|
+
`})}),`
|
|
16
|
+
`,(0,c.jsx)(t.p,{children:`Ваш тип может добавлять поля:`}),`
|
|
17
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`type ReportPreset = PresetOption<"daily" | "monthly"> & {
|
|
18
|
+
icon: string;
|
|
19
|
+
};
|
|
20
|
+
`})}),`
|
|
21
|
+
`,(0,c.jsx)(t.h2,{id:`normalizepresetids`,children:(0,c.jsx)(t.code,{children:`normalizePresetIds`})}),`
|
|
22
|
+
`,(0,c.jsxs)(t.p,{children:[`Функция предназначена для явной boundary восстановления сохранённого `,(0,c.jsx)(t.code,{children:`unknown`}),`:`]}),`
|
|
23
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`type PresetId = "first" | "second" | "third";
|
|
24
|
+
|
|
25
|
+
function isPresetId(value: unknown): value is PresetId {
|
|
26
|
+
return value === "first" || value === "second" || value === "third";
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
normalizePresetIds(["second", "unknown", "second", "first"], isPresetId);
|
|
30
|
+
// ["second", "first"].
|
|
31
|
+
`})}),`
|
|
32
|
+
`,(0,c.jsx)(t.p,{children:`Алгоритм:`}),`
|
|
33
|
+
`,(0,c.jsxs)(t.ul,{children:[`
|
|
34
|
+
`,(0,c.jsxs)(t.li,{children:[`если `,(0,c.jsx)(t.code,{children:`value`}),` не массив — возвращается копия `,(0,c.jsx)(t.code,{children:`fallbackIds`}),`;`]}),`
|
|
35
|
+
`,(0,c.jsx)(t.li,{children:`если это массив — fallback не используется, даже для пустого массива;`}),`
|
|
36
|
+
`,(0,c.jsx)(t.li,{children:`элементы проверяются переданным type guard;`}),`
|
|
37
|
+
`,(0,c.jsx)(t.li,{children:`invalid ids пропускаются;`}),`
|
|
38
|
+
`,(0,c.jsx)(t.li,{children:`дубликаты удаляются;`}),`
|
|
39
|
+
`,(0,c.jsx)(t.li,{children:`сохраняется порядок первого допустимого вхождения.`}),`
|
|
40
|
+
`]}),`
|
|
41
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`normalizePresetIds(undefined, isPresetId, ["third"]); // ["third"].
|
|
42
|
+
normalizePresetIds([], isPresetId, ["third"]); // [].
|
|
43
|
+
`})}),`
|
|
44
|
+
`,(0,c.jsx)(t.p,{children:`Это normalizer сохранённого payload. Не вызывайте его внутри обычного input/store setter, если пользовательский draft должен храниться буквально.`}),`
|
|
45
|
+
`,(0,c.jsx)(t.h2,{id:`resolvepresetoptionsbyids`,children:(0,c.jsx)(t.code,{children:`resolvePresetOptionsByIds`})}),`
|
|
46
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`const options = [
|
|
47
|
+
{ id: "first", label: "Первый" },
|
|
48
|
+
{ id: "second", label: "Второй" },
|
|
49
|
+
{ id: "third", label: "Третий" }
|
|
50
|
+
] as const;
|
|
51
|
+
|
|
52
|
+
const selected = resolvePresetOptionsByIds(["third", "first", "third", "missing"], options);
|
|
53
|
+
// objects third, first.
|
|
54
|
+
`})}),`
|
|
55
|
+
`,(0,c.jsx)(t.p,{children:`Правила:`}),`
|
|
56
|
+
`,(0,c.jsxs)(t.ul,{children:[`
|
|
57
|
+
`,(0,c.jsxs)(t.li,{children:[`порядок берётся из `,(0,c.jsx)(t.code,{children:`presetIds`}),`, а не из `,(0,c.jsx)(t.code,{children:`options`}),`;`]}),`
|
|
58
|
+
`,(0,c.jsx)(t.li,{children:`повторные ids добавляются один раз;`}),`
|
|
59
|
+
`,(0,c.jsxs)(t.li,{children:[`отсутствующие в `,(0,c.jsx)(t.code,{children:`options`}),` ids пропускаются;`]}),`
|
|
60
|
+
`,(0,c.jsx)(t.li,{children:`возвращается новый массив;`}),`
|
|
61
|
+
`,(0,c.jsx)(t.li,{children:`сами option objects не клонируются;`}),`
|
|
62
|
+
`,(0,c.jsxs)(t.li,{children:[`если в `,(0,c.jsx)(t.code,{children:`options`}),` повторяется id, `,(0,c.jsx)(t.code,{children:`Map`}),` оставляет последнюю option с этим id.`]}),`
|
|
63
|
+
`]}),`
|
|
64
|
+
`,(0,c.jsx)(t.h2,{id:`getpresetoption`,children:(0,c.jsx)(t.code,{children:`getPresetOption`})}),`
|
|
65
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`getPresetOption("second", options);
|
|
66
|
+
// { id: "second", label: "Второй" }.
|
|
67
|
+
|
|
68
|
+
getPresetOption("missing", options); // null.
|
|
69
|
+
getPresetOption(undefined, options); // null.
|
|
70
|
+
`})}),`
|
|
71
|
+
`,(0,c.jsxs)(t.p,{children:[`Функция использует первое совпадение `,(0,c.jsx)(t.code,{children:`options.find`}),`. Пустой id `,(0,c.jsx)(t.code,{children:`""`}),` считается отсутствующим и возвращает `,(0,c.jsx)(t.code,{children:`null`}),`.`]}),`
|
|
72
|
+
`,(0,c.jsx)(t.h2,{id:`saverestore-recipe`,children:`Save/restore recipe`}),`
|
|
73
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`function restorePresetIds(value: unknown): PresetId[] {
|
|
74
|
+
return normalizePresetIds(value, isPresetId, ["daily"]);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function buildPresetView(ids: readonly PresetId[]) {
|
|
78
|
+
return resolvePresetOptionsByIds(ids, PRESET_OPTIONS);
|
|
79
|
+
}
|
|
80
|
+
`})}),`
|
|
81
|
+
`,(0,c.jsx)(t.p,{children:`Разделяйте:`}),`
|
|
82
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-text`,children:`unknown persisted payload ── normalizePresetIds ──► canonical ids
|
|
83
|
+
literal UI draft ── clone only ──► literal copy
|
|
84
|
+
canonical ids ── resolve... ──► option objects for UI
|
|
85
|
+
`})}),`
|
|
86
|
+
`,(0,c.jsx)(t.h2,{id:`api-и-ошибки`,children:`API и ошибки`}),`
|
|
87
|
+
`,(0,c.jsxs)(t.table,{children:[(0,c.jsx)(t.thead,{children:(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.th,{children:`Export`}),(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:`PresetOption`})}),(0,c.jsxs)(t.td,{children:[`Минимальный `,(0,c.jsx)(t.code,{children:`{ id, label }`}),` contract`]})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`normalizePresetIds`})}),(0,c.jsx)(t.td,{children:`Проверенные уникальные ids`})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`resolvePresetOptionsByIds`})}),(0,c.jsx)(t.td,{children:`Options в порядке ids`})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`getPresetOption`})}),(0,c.jsxs)(t.td,{children:[`Option или `,(0,c.jsx)(t.code,{children:`null`})]})]})]})]}),`
|
|
88
|
+
`,(0,c.jsx)(t.p,{children:`Типичные ошибки:`}),`
|
|
89
|
+
`,(0,c.jsxs)(t.ul,{children:[`
|
|
90
|
+
`,(0,c.jsx)(t.li,{children:`Ожидать fallback для пустого массива.`}),`
|
|
91
|
+
`,(0,c.jsx)(t.li,{children:`Считать result options глубокими копиями.`}),`
|
|
92
|
+
`,(0,c.jsx)(t.li,{children:`Использовать normalizer во время пользовательского ввода.`}),`
|
|
93
|
+
`,(0,c.jsx)(t.li,{children:`Передавать type guard, который делает unsafe cast вместо runtime-проверки.`}),`
|
|
94
|
+
`,(0,c.jsx)(t.li,{children:`Ожидать, что неизвестный id будет создан автоматически.`}),`
|
|
95
|
+
`]})]})}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};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{n as e}from"./rolldown-runtime-DkW27tQK.js";import{n as t}from"./iframe-
|
|
1
|
+
import{n as e}from"./rolldown-runtime-DkW27tQK.js";import{n as t}from"./iframe-o7sH2IXC.js";import{i as n,r}from"./react-Bl2r1tuC.js";import{l as i,m as a}from"./blocks-BY40djCc.js";function o(e){let t={a:`a`,code:`code`,h1:`h1`,h2:`h2`,h3:`h3`,li:`li`,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/Formatters/Date`}),`
|
|
2
2
|
`,(0,c.jsx)(t.h1,{id:`даты-время-и-календарные-диапазоны`,children:`Даты, время и календарные диапазоны`}),`
|
|
3
3
|
`,(0,c.jsx)(t.p,{children:`Модуль решает четыре связанные задачи:`}),`
|
|
4
4
|
`,(0,c.jsxs)(t.ul,{children:[`
|