@dxtmisha/wiki 0.59.1 → 0.64.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/dist/{defineProperty-CbNEU1Ei.js → defineProperty-j1GyHeIL.js} +4 -4
  2. package/dist/library.js +1 -1
  3. package/dist/media.js +16 -3
  4. package/dist/src/media/descriptions/wikiDescriptionsBleed.d.ts +7 -0
  5. package/dist/src/media/descriptions/wikiDescriptionsDivider.d.ts +7 -0
  6. package/dist/src/media/descriptions/wikiDescriptionsSwitch.d.ts +7 -0
  7. package/dist/src/media/descriptions/wikiDescriptionsTextDescription.d.ts +7 -0
  8. package/dist/src/media/descriptions/wikiDescriptionsTextLabel.d.ts +7 -0
  9. package/dist/src/media/mdx/Bleed/wikiMdxBleed.d.ts +7 -0
  10. package/dist/src/media/mdx/Divider/wikiMdxDivider.d.ts +7 -0
  11. package/dist/src/media/mdx/Switch/wikiMdxSwitch.d.ts +7 -0
  12. package/dist/src/media/mdx/TextDescription/wikiMdxTextDescription.d.ts +7 -0
  13. package/dist/src/media/mdx/TextLabel/wikiMdxTextLabel.d.ts +7 -0
  14. package/dist/storybook.js +2398 -1746
  15. package/dist/{wikiDescriptions-Dbkpa2Je.js → wikiDescriptions-n3cFkYRZ.js} +176 -0
  16. package/package.json +1 -1
  17. package/src/media/functional/functional/api/api.en.mdx +27 -0
  18. package/src/media/functional/functional/api/api.ru.mdx +27 -0
  19. package/src/media/functional/functional/api/api.vi.mdx +27 -0
  20. package/src/media/functional/functional/composables/useApiAsyncRef/useApiAsyncRef.en.mdx +22 -1
  21. package/src/media/functional/functional/composables/useApiAsyncRef/useApiAsyncRef.ru.mdx +22 -1
  22. package/src/media/functional/functional/composables/useApiAsyncRef/useApiAsyncRef.vi.mdx +22 -1
  23. package/src/media/functional/functional/composables/useApiDelete/useApiDelete.en.mdx +19 -15
  24. package/src/media/functional/functional/composables/useApiDelete/useApiDelete.ru.mdx +19 -15
  25. package/src/media/functional/functional/composables/useApiDelete/useApiDelete.vi.mdx +22 -18
  26. package/src/media/functional/functional/composables/useApiGet/useApiGet.en.mdx +20 -15
  27. package/src/media/functional/functional/composables/useApiGet/useApiGet.ru.mdx +20 -15
  28. package/src/media/functional/functional/composables/useApiGet/useApiGet.vi.mdx +23 -18
  29. package/src/media/functional/functional/composables/{useApiManagementRef → useApiManagementAsyncRef}/useApiManagementAsyncRef.en.mdx +15 -2
  30. package/src/media/functional/functional/composables/{useApiManagementRef → useApiManagementAsyncRef}/useApiManagementAsyncRef.ru.mdx +15 -2
  31. package/src/media/functional/functional/composables/{useApiManagementRef → useApiManagementAsyncRef}/useApiManagementAsyncRef.vi.mdx +15 -2
  32. package/src/media/functional/functional/composables/useApiManagementRef/useApiManagementRef.en.mdx +10 -2
  33. package/src/media/functional/functional/composables/useApiManagementRef/useApiManagementRef.ru.mdx +12 -4
  34. package/src/media/functional/functional/composables/useApiManagementRef/useApiManagementRef.vi.mdx +10 -2
  35. package/src/media/functional/functional/composables/useApiPost/useApiPost.en.mdx +20 -15
  36. package/src/media/functional/functional/composables/useApiPost/useApiPost.ru.mdx +20 -15
  37. package/src/media/functional/functional/composables/useApiPost/useApiPost.vi.mdx +23 -18
  38. package/src/media/functional/functional/composables/useApiPut/useApiPut.en.mdx +23 -18
  39. package/src/media/functional/functional/composables/useApiPut/useApiPut.ru.mdx +23 -18
  40. package/src/media/functional/functional/composables/useApiPut/useApiPut.vi.mdx +26 -21
  41. package/src/media/functional/functional/composables/useApiRef/useApiRef.en.mdx +2 -0
  42. package/src/media/functional/functional/composables/useApiRef/useApiRef.ru.mdx +2 -0
  43. package/src/media/functional/functional/composables/useApiRef/useApiRef.vi.mdx +2 -0
  44. package/src/media/functional/functional/composables/useApiRequest/useApiRequest.en.mdx +23 -17
  45. package/src/media/functional/functional/composables/useApiRequest/useApiRequest.ru.mdx +23 -17
  46. package/src/media/functional/functional/composables/useApiRequest/useApiRequest.vi.mdx +26 -20
  47. package/src/media/functional/functional/dxt-functional-plugin/dxt-functional-plugin.en.mdx +16 -2
  48. package/src/media/functional/functional/dxt-functional-plugin/dxt-functional-plugin.ru.mdx +16 -2
  49. package/src/media/functional/functional/dxt-functional-plugin/dxt-functional-plugin.vi.mdx +16 -2
  50. package/src/media/functional/functional/functions/dxtFunctionalPlugin/dxtFunctionalPlugin.en.mdx +4 -1
  51. package/src/media/functional/functional/functions/dxtFunctionalPlugin/dxtFunctionalPlugin.ru.mdx +4 -1
  52. package/src/media/functional/functional/functions/dxtFunctionalPlugin/dxtFunctionalPlugin.vi.mdx +4 -1
  53. package/src/media/functional/functional-basic/api/api.en.mdx +55 -0
  54. package/src/media/functional/functional-basic/api/api.ru.mdx +55 -0
  55. package/src/media/functional/functional-basic/api/api.vi.mdx +55 -0
  56. package/src/media/functional/functional-basic/classes/ApiError/ApiError.en.mdx +44 -0
  57. package/src/media/functional/functional-basic/classes/ApiError/ApiError.ru.mdx +44 -0
  58. package/src/media/functional/functional-basic/classes/ApiError/ApiError.vi.mdx +44 -0
  59. package/src/media/functional/functional-basic/classes/ApiErrorItem/ApiErrorItem.en.mdx +31 -0
  60. package/src/media/functional/functional-basic/classes/ApiErrorItem/ApiErrorItem.ru.mdx +31 -0
  61. package/src/media/functional/functional-basic/classes/ApiErrorItem/ApiErrorItem.vi.mdx +31 -0
  62. package/src/media/functional/functional-basic/classes/ApiErrorStorage/ApiErrorStorage.en.mdx +51 -0
  63. package/src/media/functional/functional-basic/classes/ApiErrorStorage/ApiErrorStorage.ru.mdx +51 -0
  64. package/src/media/functional/functional-basic/classes/ApiErrorStorage/ApiErrorStorage.vi.mdx +51 -0
@@ -330,6 +330,36 @@ var e = [
330
330
  description: "\nSmall visual indicator used to display status, counts, notifications, or short labels (tags). Typically positioned over the corner of another element (like an icon or avatar) or used inline.\nFeatures numeric handling with label-max cap (e.g., \"99+\"), dot-only mode for status indication, and support for icons. Includes flexible positioning (overlap: rectangular or circular) and various color variants.\nControlled primarily through the label, icon, and dot props. Use for unread counts, online status indicators, or marking items as \"New\" or \"Sale\" in e-commerce contexts.\n "
331
331
  }
332
332
  },
333
+ {
334
+ name: "Bleed",
335
+ description: {
336
+ en: "A component that allows content to expand beyond the horizontal boundaries of its parent container",
337
+ ru: "Компонент, позволяющий контенту выходить за горизонтальные границы родительского контейнера"
338
+ },
339
+ possibilities: {
340
+ en: [
341
+ "automatic calculation of negative margins",
342
+ "flexible tag selection",
343
+ "useful for full-width images or blocks in padded containers"
344
+ ],
345
+ ru: [
346
+ "автоматический расчет отрицательных отступов",
347
+ "гибкий выбор HTML-тега",
348
+ "полезно для изображений или блоков во всю ширину в контейнерах с отступами"
349
+ ]
350
+ },
351
+ import: [],
352
+ render: "\n <DesignComponent v-bind=\"args\">\n <p>Bleed allows content to expand beyond the horizontal boundaries of its parent container.</p>\n <p>This is useful for full-width images or decorative blocks in articles.</p>\n <p>The component applies negative horizontal margins based on the margin-x property.</p>\n </DesignComponent>\n ",
353
+ stories: [],
354
+ documentation: {
355
+ body: "\n<StorybookDescriptions componentName={'Bleed'} type={'bleed'}/>\n ",
356
+ slots: "\n<StorybookDescriptions componentName={'Slot'} type={'default'}/>\n "
357
+ },
358
+ ai: {
359
+ render: "\n<div :class=\"classDemo.item\">\n <Bleed v-bind=\"args\">\n <p>The component allows content to expand beyond the boundaries of the parent container by applying negative horizontal margins.</p>\n </Bleed>\n</div>\n ",
360
+ description: "\nThe Bleed component is used to break elements out of their parent container's horizontal padding. It applies negative horizontal margins equal to the specified margin-x value.\nCommonly used in article layouts to make images or breakout sections take up the full width of the viewport or a wider area than the text column.\n "
361
+ }
362
+ },
333
363
  {
334
364
  name: "Bars",
335
365
  description: {
@@ -961,6 +991,29 @@ var e = [
961
991
  description: "\nSpecialized modal component for standardized user interactions such as alerts, confirmations, and status messages. Extends the Modal component with a predefined layout for icons, titles, and action buttons.\nFeatures built-in success/error states with automatic icon switching and content styling. Supports flexible positioning of images (top/left) and integrates with Window, Bars, and Actions for a consistent footer.\nControlled via v-model:open and various content props (label, description). Use for critical operations requiring user confirmation, operation success/fail alerts, or informative system messages.\n "
962
992
  }
963
993
  },
994
+ {
995
+ name: "Divider",
996
+ description: {
997
+ en: "A component for visual separation of content blocks",
998
+ ru: "Компонент для визуального разделения блоков контента"
999
+ },
1000
+ possibilities: {
1001
+ en: [
1002
+ "customizable line width and color via tokens",
1003
+ "clean and minimal design",
1004
+ "used to improve visual hierarchy"
1005
+ ],
1006
+ ru: [
1007
+ "настраиваемая ширина и цвет линии через токены",
1008
+ "чистый и минималистичный дизайн",
1009
+ "используется для улучшения визуальной иерархии"
1010
+ ]
1011
+ },
1012
+ import: [],
1013
+ stories: [],
1014
+ documentation: { body: "\n<StorybookDescriptions componentName={'Divider'} type={'divider'}/>\n " },
1015
+ ai: { description: "\nA simple horizontal line used to separate content or sections. It helps in organizing information and creating a clear visual structure in the interface.\n " }
1016
+ },
964
1017
  {
965
1018
  name: "Dummy",
966
1019
  description: {
@@ -2738,6 +2791,73 @@ var e = [
2738
2791
  },
2739
2792
  ai: { description: "\nVisual representation element for a single notification message, typically orchestrated by the Snackbar component. Designed for concise informational alerts, success messages, or quick-action prompts.\nFeatures a flexible internal structure with support for labels, detailed descriptions, and material-symbol icons (leading/trailing). Includes integrated action button support, a mandatory close button, and support for rendering custom HTML or Vue components as message bodies.\nControlled via simple content props or an actions-list array for complex button configurations. Use as the base message unit for all system feedback, ensuring high visibility and accessibility through automatic ARIA status role implementation.\n " }
2740
2793
  },
2794
+ {
2795
+ name: "Switch",
2796
+ description: {
2797
+ en: "Interactive toggle switch component for binary on/off state selection",
2798
+ ru: "Интерактивный переключатель (тогл) для выбора бинарного состояния «включено»/«выключено»"
2799
+ },
2800
+ possibilities: {
2801
+ en: [
2802
+ "binary toggling states (on / off)",
2803
+ "built-in validation support with custom messages",
2804
+ "label and description text support",
2805
+ "customizable track and slider elements",
2806
+ "disabled and loading states",
2807
+ "ripple effect on interaction",
2808
+ "skeleton state for loading placeholders",
2809
+ "adaptive layout options",
2810
+ "form integration with name and value attributes"
2811
+ ],
2812
+ ru: [
2813
+ "бинарные переключаемые состояния (вкл / выкл)",
2814
+ "встроенная поддержка валидации с пользовательскими сообщениями",
2815
+ "поддержка текста метки и описания",
2816
+ "настраиваемые элементы трека и ползунка",
2817
+ "состояния отключения и загрузки",
2818
+ "эффект волны при взаимодействии",
2819
+ "состояние скелетона для заполнителей загрузки",
2820
+ "опции адаптивной разметки",
2821
+ "интеграция с формами через атрибуты name и value"
2822
+ ]
2823
+ },
2824
+ import: ["import { ref } from 'vue'"],
2825
+ stories: [
2826
+ {
2827
+ id: "SwitchVModel",
2828
+ name: {
2829
+ en: "Two-way binding (v-model)",
2830
+ ru: "Двусторонняя привязка (v-model)"
2831
+ },
2832
+ setup: "\n return {\n switchValue: ref(false)\n }\n ",
2833
+ template: "\n <div class=\"wiki-storybook-flex-column\">\n <div class=\"wiki-storybook-flex\">\n <button class=\"wiki-storybook-button\" @click=\"switchValue = !switchValue\">Toggle {{ switchValue }}</button>\n </div>\n <DesignComponent\n v-model=\"switchValue\"\n label=\"Switch with v-model\"\n />\n </div>\n "
2834
+ },
2835
+ {
2836
+ id: "SwitchSkeleton",
2837
+ name: {
2838
+ en: "Skeleton",
2839
+ ru: "Скелетон"
2840
+ },
2841
+ components: ["Skeleton"],
2842
+ template: "\n <DesignSkeleton :active=\"true\">\n <div class=\"wiki-storybook-flex-column\">\n <DesignComponent isSkeleton label=\"Loading switch\" />\n <DesignComponent isSkeleton label=\"Another loading switch\" />\n </div>\n </DesignSkeleton>\n "
2843
+ },
2844
+ {
2845
+ id: "SwitchSlots",
2846
+ name: {
2847
+ en: "Slots usage",
2848
+ ru: "Использование слотов"
2849
+ },
2850
+ template: "\n <DesignComponent>\n <template #default>\n <strong>Custom label slot</strong>\n </template>\n <template #description>\n <em>Custom description slot</em>\n </template>\n </DesignComponent>\n "
2851
+ }
2852
+ ],
2853
+ documentation: {
2854
+ body: "\n<StorybookDescriptions componentName={'Switch'} type={'switch'}/>\n\n<StorybookDescriptions componentName={'Checkbox'} type={'value'}/>\n<StorybookDescriptions componentName={'Checkbox'} type={'selected'}/>\n<StorybookDescriptions componentName={'Value'} type={'v-model'}/>\n<Canvas of={Component.SwitchVModel}/>\n\n<StorybookDescriptions componentName={'Style'} type={'isSkeleton'}/>\n<Canvas of={Component.SwitchSkeleton}/>\n ",
2855
+ events: "\n<StorybookDescriptions componentName={'Event'} type={'input'}/>\n<StorybookDescriptions componentName={'Event'} type={'change'}/>\n ",
2856
+ expose: "\n<StorybookDescriptions componentName={'Expose'} type={'value'}/>\n<StorybookDescriptions componentName={'Expose'} type={'checkValidity'}/>\n<StorybookDescriptions componentName={'Expose'} type={'validationMessage'}/>\n ",
2857
+ slots: "\n<Canvas of={Component.SwitchSlots}/>\n<StorybookDescriptions componentName={'Slot'} type={'label'}/>\n<StorybookDescriptions componentName={'Slot'} type={'description'}/>\n "
2858
+ },
2859
+ ai: { description: "\nForm control component representing a physical switch to toggle settings or binary choices on/off.\nInherits behavior and accessibility features from Checkbox but provides a distinct sliding track visual representation.\nSupports primary labels, details descriptions, custom track customization, built-in validation states, loading states, and adaptive design layouts.\nControlled via v-model and emits @input/@change events. Use for instant toggles of features or preferences.\n " }
2860
+ },
2741
2861
  {
2742
2862
  name: "TabItem",
2743
2863
  description: {
@@ -2948,6 +3068,62 @@ var e = [
2948
3068
  },
2949
3069
  ai: { description: "\nLow-level functional engine for multi-line inputs that provides precise, real-time height adjustment based on content. Implements a reliable cloning mechanism to calculate scroll-free container heights while respecting parent padding and font styles.\nFeatures automated height synchronization during content changes, supporting smooth CSS transitions and native textarea attributes via inputAttrs. Operates as a foundational tool for the Textarea component, ensuring character entry never triggers unwanted shift or overflow.\nPrimarily integrated as a subcomponent; should generally not be manually used for standalone input fields. Controlled via reactive value bindings, serving as the high-performance core for any dynamic data entry element requiring responsive layout scaling.\n " }
2950
3070
  },
3071
+ {
3072
+ name: "TextDescription",
3073
+ description: {
3074
+ en: "A simple component for displaying text description with dynamic HTML tag support",
3075
+ ru: "Простой компонент для отображения текстового описания с поддержкой динамического HTML-тега"
3076
+ },
3077
+ possibilities: {
3078
+ en: [
3079
+ "renders text from description property or description slot",
3080
+ "supports dynamic HTML tags (span, div, p, etc.)",
3081
+ "fully compatible with standard design tokens",
3082
+ "clean and lightweight DOM output"
3083
+ ],
3084
+ ru: [
3085
+ "выводит текст из свойства description или слота описания",
3086
+ "поддерживает динамические HTML-теги (span, div, p и т.д.)",
3087
+ "полностью совместим со стандартными токенами дизайна",
3088
+ "чистый и легковесный DOM"
3089
+ ]
3090
+ },
3091
+ import: [],
3092
+ stories: [],
3093
+ documentation: {
3094
+ body: "\n<StorybookDescriptions componentName={'TextDescription'} type={'textDescription'}/>\n ",
3095
+ slots: "\n<StorybookDescriptions componentName={'Slot'} type={'description'}/>\n "
3096
+ },
3097
+ ai: { description: "\nA utility component for displaying textual descriptions. Supports description slot injection, custom HTML tags via \"tag\" property (defaults to \"span\"), and clean semantic output. Integrated with DescriptionInclude for standardized description rendering.\n " }
3098
+ },
3099
+ {
3100
+ name: "TextLabel",
3101
+ description: {
3102
+ en: "A simple component for displaying text or labels with dynamic HTML tag support",
3103
+ ru: "Простой компонент для отображения текста или меток с поддержкой динамического HTML-тега"
3104
+ },
3105
+ possibilities: {
3106
+ en: [
3107
+ "renders text from label property or default slot",
3108
+ "supports dynamic HTML tags (span, div, p, h1-h6, etc.)",
3109
+ "fully compatible with standard design tokens",
3110
+ "clean and lightweight DOM output"
3111
+ ],
3112
+ ru: [
3113
+ "выводит текст из свойства label или слота по умолчанию",
3114
+ "поддерживает динамические HTML-теги (span, div, p, h1-h6 и т.д.)",
3115
+ "полностью совместим со стандартными токенами дизайна",
3116
+ "чистый и легковесный DOM"
3117
+ ]
3118
+ },
3119
+ import: [],
3120
+ stories: [],
3121
+ documentation: {
3122
+ body: "\n<StorybookDescriptions componentName={'TextLabel'} type={'textLabel'}/>\n ",
3123
+ slots: "\n<StorybookDescriptions componentName={'Slot'} type={'default'}/>\n "
3124
+ },
3125
+ ai: { description: "\nA utility component for displaying text and labels. Supports slot injection, custom HTML tags via \"tag\" property (defaults to \"span\"), and clean semantic output. Integrated with LabelInclude for standardized text rendering.\n " }
3126
+ },
2951
3127
  {
2952
3128
  name: "Tooltip",
2953
3129
  description: {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@dxtmisha/wiki",
3
3
  "private": false,
4
- "version": "0.59.1",
4
+ "version": "0.64.0",
5
5
  "type": "module",
6
6
  "description": "Wiki documentation and storybook utilities for DXT UI design system",
7
7
  "keywords": [
@@ -13,9 +13,11 @@ The main task of these tools is to automate routine operations: tracking loading
13
13
  ## Available Tools
14
14
 
15
15
  - `useApiRef` — Reactive data retrieval (GET) with automatic execution and storage in a `ref`.
16
+ - `useApiAsyncRef` — Asynchronous version of `useApiRef` for immediate initialization (SSR).
16
17
  - `useApiRequest` — Base hook for manual execution of any HTTP requests (returns the `send` method).
17
18
  - `useApiPost / Put / Delete` — Specialized wrappers for mutations (create, update, delete).
18
19
  - `useApiManagementRef` — A comprehensive orchestrator combining GET requests, search, formatting, and mutations into a single cycle.
20
+ - `useApiManagementAsyncRef` — Asynchronous orchestrator for immediate initialization (SSR).
19
21
 
20
22
  ## How to Work with Them
21
23
 
@@ -71,4 +73,29 @@ const {
71
73
  // After calling sendDelete(), the main 'list' will update AUTOMATICALLY!
72
74
  ```
73
75
 
76
+ ## Error Handling
77
+
78
+ The API hooks use a contract-based error management system. Instead of manually handling every response status in your components, you define a "base" of expected errors and let the system resolve them automatically.
79
+
80
+ ### Workflow:
81
+ 1. **Define a Contract (`errorContract`)**: You pass a list of potential error patterns (a contract) to the hook. This serves as a database of errors you want to handle specifically.
82
+ 2. **Automatic Matching**: When a request fails (status ≥ 400), the system compares the response against your contract. It matches based on:
83
+ * **HTTP Status**: e.g., `404` or `500`.
84
+ * **Error Code**: A specific string code extracted from the JSON response body (e.g., `'USER_NOT_FOUND'`).
85
+ * **URL Pattern**: Specific endpoints or patterns (RegExp).
86
+ * **Custom Validation**: A function that returns `true` if the response matches the error.
87
+ 3. **Data Resolution**: If a match is found, the system populates the reactive `errorItem` property with structured data, including the localized message and the resolved error code.
88
+ 4. **UI Implementation**: In your component, you simply use the `errorItem` to display messages or toggle UI states, confident that the matching logic is handled centrally.
89
+
90
+ This system ensures that your components remain clean and focused on display logic, while error identification remains declarative and reusable.
91
+
92
+ ## Server-Side Rendering (SSR)
93
+
94
+ All API hooks are designed with **Server-Side Rendering (SSR)** support in mind. To ensure data is pre-fetched on the server before the page is sent to the client, you have two options:
95
+
96
+ 1. **Async Versions**: Use `useApiAsyncRef` or `useApiManagementAsyncRef`. These hooks automatically call `initSsr()` upon creation, ensuring the request is executed during server-side rendering.
97
+ 2. **Manual `initSsr()`**: For standard hooks (like `useApiRef`), you must explicitly call the `.initSsr()` method inside the component's `setup()` block.
98
+
99
+ This prevents "content flickering" (where users see empty states or skeletons followed by data loading on the client) and improves SEO by providing fully populated HTML from the server.
100
+
74
101
  This architecture allows you to describe data logic declaratively, focusing on request configuration rather than manual management of loading states and list updates.
@@ -13,9 +13,11 @@ import {Meta} from '@storybook/addon-docs/blocks'
13
13
  ## Доступные инструменты
14
14
 
15
15
  - `useApiRef` — Реактивное получение данных (GET) с автоматическим запуском и хранением в `ref`.
16
+ - `useApiAsyncRef` — Асинхронная версия `useApiRef` для немедленной инициализации (SSR).
16
17
  - `useApiRequest` — Базовый хук для ручного выполнения любых HTTP-запросов (возвращает метод `send`).
17
18
  - `useApiPost / Put / Delete` — Специализированные обертки для мутаций (создание, обновление, удаление).
18
19
  - `useApiManagementRef` — Комплексный оркестратор, объединяющий GET-запросы, поиск, форматирование и мутации в единый цикл.
20
+ - `useApiManagementAsyncRef` — Асинхронный оркестратор для немедленной инициализации (SSR).
19
21
 
20
22
  ## Как с ними работать
21
23
 
@@ -71,4 +73,29 @@ const {
71
73
  // После вызова sendDelete() основной список list обновится САМ!
72
74
  ```
73
75
 
76
+ ## Работа с ошибками
77
+
78
+ Хуки API используют систему управления ошибками на основе контрактов. Вместо того чтобы вручную обрабатывать каждый статус ответа в компонентах, вы определяете «базу» ожидаемых ошибок, и система разрешает их автоматически.
79
+
80
+ ### Процесс работы:
81
+ 1. **Определение контракта (`errorContract`)**: Вы передаете хуку список возможных шаблонов ошибок (контракт). Это служит вашей базой данных для ошибок, которые требуют специфической обработки.
82
+ 2. **Автоматическое сопоставление**: Если запрос завершается неудачей (статус ≥ 400), система сравнивает ответ с вашим контрактом. Сопоставление происходит по следующим критериям:
83
+ * **HTTP-статус**: например, `404` или `500`.
84
+ * **Код ошибки**: специфический строковый код, извлеченный из JSON-тела ответа (например, `'USER_NOT_FOUND'`).
85
+ * **Шаблон URL**: конкретные эндпоинты или паттерны (RegExp).
86
+ * **Пользовательская валидация**: функция, которая возвращает `true`, если ответ соответствует ошибке.
87
+ 3. **Разрешение данных**: Если совпадение найдено, система заполняет реактивное свойство `errorItem` структурированными данными, включая локализованное сообщение и разрешенный код ошибки.
88
+ 4. **Реализация в UI**: В своем компоненте вы просто используете `errorItem` для отображения сообщений или переключения состояний интерфейса, будучи уверенными, что логика идентификации ошибок вынесена в контракт.
89
+
90
+ Эта система гарантирует, что ваши компоненты останутся чистыми и сфокусированными на логике отображения, в то время как идентификация ошибок остается декларативной и переиспользуемой.
91
+
92
+ ## Работа в SSR
93
+
94
+ Все хуки для работы с API спроектированы с учетом поддержки **Server-Side Rendering (SSR)**. Чтобы данные были предзагружены на сервере до отправки страницы клиенту, у вас есть два варианта:
95
+
96
+ 1. **Асинхронные версии**: Используйте `useApiAsyncRef` или `useApiManagementAsyncRef`. Эти хуки автоматически вызывают `initSsr()` при создании, что гарантирует выполнение запроса во время серверного рендеринга.
97
+ 2. **Ручной вызов `initSsr()`**: Для стандартных хуков (например, `useApiRef`) необходимо явно вызвать метод `.initSsr()` внутри блока `setup()` компонента.
98
+
99
+ Это позволяет избежать «мерцания» контента (когда пользователь видит пустую страницу или скелетон, а затем данные подгружаются на клиенте) и улучшает SEO, предоставляя полностью заполненный HTML с сервера.
100
+
74
101
  Такая архитектура позволяет описывать логику работы с данными декларативно, фокусируясь на конфигурации запросов, а не на ручном управлении состояниями загрузки и обновлении списков.
@@ -13,9 +13,11 @@ Nhiệm vụ chính của các công cụ này là tự động hóa các tác v
13
13
  ## Các công cụ hiện có
14
14
 
15
15
  - `useApiRef` — Truy xuất dữ liệu phản hồi (GET) với tính năng tự động chạy và lưu trữ trong `ref`.
16
+ - `useApiAsyncRef` — Phiên bản bất đồng bộ của `useApiRef` để khởi tạo ngay lập tức (SSR).
16
17
  - `useApiRequest` — Hook cơ bản để thực hiện thủ công bất kỳ yêu cầu HTTP nào (trả về phương thức `send`).
17
18
  - `useApiPost / Put / Delete` — Các lớp vỏ chuyên dụng cho các thay đổi (tạo, cập nhật, xóa).
18
19
  - `useApiManagementRef` — Bộ điều phối toàn diện, kết hợp các yêu cầu GET, tìm kiếm, định dạng và thay đổi thành một chu kỳ duy nhất.
20
+ - `useApiManagementAsyncRef` — Bộ điều phối bất đồng bộ để khởi tạo ngay lập tức (SSR).
19
21
 
20
22
  ## Cách làm việc với chúng
21
23
 
@@ -71,4 +73,29 @@ const {
71
73
  // Sau khi gọi sendDelete(), danh sách chính 'list' sẽ TỰ ĐỘNG cập nhật!
72
74
  ```
73
75
 
76
+ ## Xử lý lỗi
77
+
78
+ Các hook API sử dụng hệ thống quản lý lỗi dựa trên hợp đồng. Thay vì xử lý thủ công từng trạng thái phản hồi trong các component, bạn xác định một "cơ sở" các lỗi dự kiến và để hệ thống tự động giải quyết chúng.
79
+
80
+ ### Quy trình làm việc:
81
+ 1. **Xác định Hợp đồng (`errorContract`)**: Bạn truyền một danh sách các mẫu lỗi tiềm năng (một hợp đồng) cho hook. Điều này đóng vai trò như một cơ sở dữ liệu về các lỗi bạn muốn xử lý cụ thể.
82
+ 2. **So khớp tự động**: Khi một yêu cầu thất bại (trạng thái ≥ 400), hệ thống sẽ so sánh phản hồi với hợp đồng của bạn. Nó khớp dựa trên:
83
+ * **Trạng thái HTTP**: ví dụ: `404` hoặc `500`.
84
+ * **Mã lỗi**: Một mã chuỗi cụ thể được trích xuất từ thân phản hồi JSON (ví dụ: `'USER_NOT_FOUND'`).
85
+ * **Mẫu URL**: Các endpoint cụ thể hoặc các mẫu (RegExp).
86
+ * **Xác thực tùy chỉnh**: Một hàm trả về `true` nếu phản hồi khớp với lỗi.
87
+ 3. **Giải quyết dữ liệu**: Nếu tìm thấy sự phù hợp, hệ thống sẽ điền vào thuộc tính reactive `errorItem` các dữ liệu có cấu trúc, bao gồm thông báo đã được bản địa hóa và mã lỗi đã được giải quyết.
88
+ 4. **Triển khai UI**: Trong component của mình, bạn chỉ cần sử dụng `errorItem` để hiển thị thông báo hoặc chuyển đổi trạng thái UI, tin tưởng rằng logic so khớp lỗi đã được xử lý tập trung.
89
+
90
+ Hệ thống này đảm bảo rằng các component của bạn luôn sạch sẽ và tập trung vào logic hiển thị, trong khi việc nhận diện lỗi vẫn mang tính khai báo và có thể tái sử dụng.
91
+
92
+ ## Server-Side Rendering (SSR)
93
+
94
+ Tất cả các hook API được thiết kế với sự hỗ trợ cho **Server-Side Rendering (SSR)**. Để đảm bảo dữ liệu được lấy trước trên máy chủ trước khi trang được gửi đến máy khách, bạn có hai lựa chọn:
95
+
96
+ 1. **Phiên bản bất đồng bộ**: Sử dụng `useApiAsyncRef` hoặc `useApiManagementAsyncRef`. Các hook này tự động gọi `initSsr()` khi được tạo, đảm bảo yêu cầu được thực thi trong quá trình render phía máy chủ.
97
+ 2. **Gọi `initSsr()` thủ công**: Đối với các hook tiêu chuẩn (như `useApiRef`), bạn phải gọi phương thức `.initSsr()` một cách rõ ràng bên trong khối `setup()` của component.
98
+
99
+ Điều này giúp ngăn chặn hiện tượng "nhấp nháy nội dung" (khi người dùng thấy trạng thái trống hoặc skeleton trước khi dữ liệu được tải ở máy khách) và cải thiện SEO bằng cách cung cấp HTML đã có đầy đủ dữ liệu từ máy chủ.
100
+
74
101
  Kiến trúc này cho phép bạn mô tả logic làm việc với dữ liệu một cách khai báo, tập trung vào cấu hình yêu cầu thay vì quản lý thủ công các trạng thái tải và cập nhật danh sách.
@@ -21,11 +21,32 @@ The parameters are identical to `useApiRef`.
21
21
  - `conditions?: RefType<boolean>` — request conditions.
22
22
  - `transformation?: (data: T, isResponseContractValid?: ApiDataValidation) => ApiData<R>` — data transformation.
23
23
  - `validateResponseContract?: (data: T) => ApiDataValidation` — contract validation.
24
+ - `errorContract?: ApiErrorStorageList` — storage of response error contracts.
24
25
  - `unmounted?: boolean` — removal from cache on unmount.
25
26
  - `apiInstance?: ApiInstance` — API instance.
26
27
 
27
28
  ## Return Value
28
- Returns the `UseApiRef<R>` object. The structure of the `UseApiRef` object is identical to the return value of [`useApiRef`](./useApiRef.en.mdx).
29
+ Returns the `UseApiRef<R>` object:
30
+
31
+ **Reactive states:**
32
+ - `data: ComputedRef<ApiData<R> | undefined>` — reactive data.
33
+ - `item: Ref<ApiData<R> | undefined>` — reactive item.
34
+ - `errorItem: ComputedRef<ApiErrorItem | undefined>` — current error object if the request failed.
35
+ - `isResponseContractValid: ComputedRef<boolean>` — `true` if the response contract is valid.
36
+ - `responseValidationResult: ComputedRef<ApiDataValidation | undefined>` — detailed contract validation result.
37
+ - `length: ComputedRef<number>` — count of elements in the list.
38
+ - `starting: ComputedRef<boolean>` — flag for initial loading phase.
39
+ - `loading: Ref<boolean>` — current loading status.
40
+ - `reading: Ref<boolean>` — flag for active data processing.
41
+
42
+ **Methods:**
43
+ - `isStarting(): boolean`, `isLoading(): boolean`, `isReading(): boolean` — status check methods.
44
+ - `getItem(): ApiData<R> | undefined` — get current data value without reactivity.
45
+ - `init(awaitFetch?: boolean): Promise<void>` — manual initialization.
46
+ - `initSsr(): void` — SSR initialization.
47
+ - `reset(): Promise<void>` — force re-run the request.
48
+ - `stop(): void` — stop observation and clear data.
49
+ - `abort(): void` — cancel the current HTTP request.
29
50
 
30
51
  ## Example
31
52
 
@@ -21,11 +21,32 @@ import {Meta} from '@storybook/addon-docs/blocks'
21
21
  - `conditions?: RefType<boolean>` — условия выполнения запроса.
22
22
  - `transformation?: (data: T, isResponseContractValid?: ApiDataValidation) => ApiData<R>` — преобразование данных.
23
23
  - `validateResponseContract?: (data: T) => ApiDataValidation` — валидация контракта.
24
+ - `errorContract?: ApiErrorStorageList` — хранилище контрактов ошибок ответа.
24
25
  - `unmounted?: boolean` — удаление из кэша при размонтировании.
25
26
  - `apiInstance?: ApiInstance` — экземпляр API.
26
27
 
27
28
  ## Возвращаемое значение
28
- Возвращает объект `UseApiRef<R>`. Состав объекта `UseApiRef` полностью идентичен возвращаемому значению [`useApiRef`](./useApiRef.ru.mdx).
29
+ Возвращает объект `UseApiRef<R>`:
30
+
31
+ **Реактивные состояния:**
32
+ - `data: ComputedRef<ApiData<R> | undefined>` — реактивные данные.
33
+ - `item: Ref<ApiData<R> | undefined>` — реактивный элемент.
34
+ - `errorItem: ComputedRef<ApiErrorItem | undefined>` — текущий объект ошибки, если запрос не удался.
35
+ - `isResponseContractValid: ComputedRef<boolean>` — `true`, если контракт ответа валиден.
36
+ - `responseValidationResult: ComputedRef<ApiDataValidation | undefined>` — подробный результат валидации контракта.
37
+ - `length: ComputedRef<number>` — количество элементов в списке.
38
+ - `starting: ComputedRef<boolean>` — флаг начальной фазы загрузки.
39
+ - `loading: Ref<boolean>` — текущий статус загрузки.
40
+ - `reading: Ref<boolean>` — флаг активной обработки данных.
41
+
42
+ **Методы:**
43
+ - `isStarting(): boolean`, `isLoading(): boolean`, `isReading(): boolean` — методы проверки статуса.
44
+ - `getItem(): ApiData<R> | undefined` — получить текущее значение данных без реактивности.
45
+ - `init(awaitFetch?: boolean): Promise<void>` — ручная инициализация.
46
+ - `initSsr(): void` — инициализация для SSR.
47
+ - `reset(): Promise<void>` — принудительный перезапуск запроса.
48
+ - `stop(): void` — остановка наблюдения и очистка данных.
49
+ - `abort(): void` — отмена текущего HTTP-запроса.
29
50
 
30
51
  ## Пример
31
52
 
@@ -21,11 +21,32 @@ Các tham số hoàn toàn giống với `useApiRef`.
21
21
  - `conditions?: RefType<boolean>` — điều kiện thực thi.
22
22
  - `transformation?: (data: T, isResponseContractValid?: ApiDataValidation) => ApiData<R>` — chuyển đổi dữ liệu.
23
23
  - `validateResponseContract?: (data: T) => ApiDataValidation` — xác thực hợp đồng dữ liệu.
24
+ - `errorContract?: ApiErrorStorageList` — nơi lưu trữ hợp đồng lỗi phản hồi.
24
25
  - `unmounted?: boolean` — có xóa khỏi cache khi unmount hay không.
25
26
  - `apiInstance?: ApiInstance` — instance của API.
26
27
 
27
28
  ## Giá trị trả về
28
- Trả về đối tượng `UseApiRef<R>`. Cấu trúc của đối tượng `UseApiRef` hoàn toàn giống với giá trị trả về của [`useApiRef`](./useApiRef.vi.mdx).
29
+ Trả về đối tượng `UseApiRef<R>`:
30
+
31
+ **Trạng thái phản ứng:**
32
+ - `data: ComputedRef<ApiData<R> | undefined>` — dữ liệu reactive.
33
+ - `item: Ref<ApiData<R> | undefined>` — phần tử reactive.
34
+ - `errorItem: ComputedRef<ApiErrorItem | undefined>` — đối tượng lỗi hiện tại nếu yêu cầu thất bại.
35
+ - `isResponseContractValid: ComputedRef<boolean>` — `true` nếu hợp đồng phản hồi hợp lệ.
36
+ - `responseValidationResult: ComputedRef<ApiDataValidation | undefined>` — kết quả chi tiết xác thực hợp đồng.
37
+ - `length: ComputedRef<number>` — số lượng phần tử trong danh sách.
38
+ - `starting: ComputedRef<boolean>` — cờ cho giai đoạn tải ban đầu.
39
+ - `loading: Ref<boolean>` — trạng thái tải hiện tại.
40
+ - `reading: Ref<boolean>` — cờ xử lý dữ liệu đang hoạt động.
41
+
42
+ **Phương thức:**
43
+ - `isStarting(): boolean`, `isLoading(): boolean`, `isReading(): boolean` — các phương thức kiểm tra trạng thái.
44
+ - `getItem(): ApiData<R> | undefined` — lấy giá trị dữ liệu hiện tại không cần phản ứng.
45
+ - `init(awaitFetch?: boolean): Promise<void>` — khởi tạo thủ công.
46
+ - `initSsr(): void` — khởi tạo cho SSR.
47
+ - `reset(): Promise<void>` — buộc chạy lại yêu cầu.
48
+ - `stop(): void` — dừng theo dõi và xóa dữ liệu.
49
+ - `abort(): void` — hủy yêu cầu HTTP hiện tại.
29
50
 
30
51
  ## Ví dụ
31
52
 
@@ -4,31 +4,35 @@ import { Meta } from '@storybook/addon-docs/blocks'
4
4
 
5
5
  # `useApiDelete`
6
6
 
7
- Returns an object with a loading state and a `send` method for executing API `DELETE` requests.
7
+ Returns an object with a loading state and a `send` method for executing API `DELETE` requests. It is a convenient wrapper over `useApiRequest` that pre-fills the `DELETE` method. Accepts settings as a single `UseApiDeleteSetup` object.
8
8
 
9
9
  **Parameters:**
10
- - `path?: RefOrNormal<string | undefined>` Path to the API endpoint (can be reactive).
11
- - `action?: (data: Return | undefined) => Promise<void> | void` Callback action to perform after the request completes successfully.
12
- - `transformation?: (data: T) => Return` Function to transform the response data before it is returned or passed to the `action`.
13
- - `toData: boolean = true` — Whether to extract the `data` field from the response.
14
- - `options?: ApiOptions` Additional request options (`ApiFetch` object parameter).
15
- - `apiInstance?: ApiInstance` API instance to use for the request. Defaults to `Api.getItem()`.
10
+ - `setup: UseApiDeleteSetup`Configuration setup object:
11
+ - `path?: RefOrNormal<string | undefined>`Path to the API endpoint (can be reactive).
12
+ - `action?: (data: Return | undefined) => Promise<void> | void` Callback action to perform after the request completes successfully.
13
+ - `transformation?: (data: T) => Return` — Function to transform the response data before it is returned or passed to the `action`.
14
+ - `validateRequestContract?: (data: Request) => ApiDataValidation & Return` Request contract validation function.
15
+ - `validateResponseContract?: (data: T) => ApiDataValidation & Return` Response contract validation function.
16
+ - `errorContract?: ApiErrorStorageList` — storage of response error contracts.
17
+ - `toData?: boolean` — Whether to extract the `data` field from the response. Defaults to `true`.
18
+ - `options?: ApiOptions` — Additional request options (`ApiFetch` object parameter).
19
+ - `apiInstance?: ApiInstance` — API instance to use for the request. Defaults to `Api.getItem()`.
16
20
 
17
21
  **Returns:**
18
22
  An object with the following properties:
19
23
  - `loading: Ref<boolean>` — Reactive loading state. It becomes `true` while the request is in progress and `false` after it completes or fails.
20
- - `send(request?: Request): Promise<Return | undefined>` — An asynchronous method for sending the `DELETE` request. It automatically manages the `loading` state, applies the transformation function to the response, executes the `action` callback on success, and safely handles errors by logging them to the console.
24
+ - `send(request?: Request): Promise<Return | undefined>` — An asynchronous method for sending the `DELETE` request. It automatically manages the `loading` state, validates the request and response contracts, applies the transformation function to the response, executes the `action` callback on success, and safely handles errors by logging them to the console.
21
25
 
22
26
  ```typescript
23
27
  import { useApiDelete } from '@dxtmisha/functional'
24
28
 
25
- const { loading, send } = useApiDelete(
26
- '/api/delete',
27
- (data) => console.log('Action complete:', data),
28
- (raw) => ({ ...raw, processed: true }),
29
- true,
30
- { cache: false }
31
- )
29
+ const { loading, send } = useApiDelete({
30
+ path: '/api/delete',
31
+ action: (data) => console.log('Action complete:', data),
32
+ transformation: (raw) => ({ ...raw, processed: true }),
33
+ toData: true,
34
+ options: { cache: false }
35
+ })
32
36
 
33
37
  const handleDelete = async () => {
34
38
  const result = await send({ id: 1 })
@@ -4,31 +4,35 @@ import { Meta } from '@storybook/addon-docs/blocks'
4
4
 
5
5
  # `useApiDelete`
6
6
 
7
- Возвращает объект с состоянием загрузки и методом `send` для выполнения `DELETE`-запросов к API.
7
+ Возвращает объект с состоянием загрузки и методом `send` для выполнения `DELETE`-запросов к API. Является удобной оберткой над `useApiRequest` с предустановленным методом `DELETE`. Принимает настройки в виде единого объекта `UseApiDeleteSetup`.
8
8
 
9
9
  **Параметры:**
10
- - `path?: RefOrNormal<string | undefined>` Путь к endpoint API (может быть реактивным).
11
- - `action?: (data: Return | undefined) => Promise<void> | void` Действие (коллбэк), выполняемое после успешного завершения запроса.
12
- - `transformation?: (data: T) => Return` — Функция трансформации ответа от сервера перед возвращением или передачей в `action`.
13
- - `toData: boolean = true` — Извлекать ли поле `data` из ответа.
14
- - `options?: ApiOptions` — Дополнительные опции запроса (объект параметров `ApiFetch`).
15
- - `apiInstance?: ApiInstance` Экземпляр API, используемый для выполнения запроса. По умолчанию `Api.getItem()`.
10
+ - `setup: UseApiDeleteSetup`Объект настроек запроса:
11
+ - `path?: RefOrNormal<string | undefined>` Путь к endpoint API (может быть реактивным).
12
+ - `action?: (data: Return | undefined) => Promise<void> | void` — Действие (коллбэк), выполняемое после успешного завершения запроса.
13
+ - `transformation?: (data: T) => Return` — Функция трансформации ответа от сервера перед возвращением или передачей в `action`.
14
+ - `validateRequestContract?: (data: Request) => ApiDataValidation & Return` — Функция валидации контракта отправляемого запроса.
15
+ - `validateResponseContract?: (data: T) => ApiDataValidation & Return` Функция валидации контракта полученного ответа.
16
+ - `errorContract?: ApiErrorStorageList` — хранилище контрактов ошибок ответа.
17
+ - `toData?: boolean` — Извлекать ли поле `data` из ответа. По умолчанию `true`.
18
+ - `options?: ApiOptions` — Дополнительные опции запроса (объект параметров `ApiFetch`).
19
+ - `apiInstance?: ApiInstance` — Экземпляр API, используемый для выполнения запроса. По умолчанию `Api.getItem()`.
16
20
 
17
21
  **Возвращает:**
18
22
  Объект со следующими свойствами:
19
23
  - `loading: Ref<boolean>` — Реактивное состояние загрузки. Принимает значение `true` во время выполнения запроса и `false` после его завершения или ошибки.
20
- - `send(request?: Request): Promise<Return | undefined>` — Асинхронный метод для отправки `DELETE`-запроса. Он автоматически управляет состоянием `loading`, применяет функцию трансформации к ответу, вызывает коллбэк `action` при успехе и безопасно обрабатывает ошибки.
24
+ - `send(request?: Request): Promise<Return | undefined>` — Асинхронный метод для отправки `DELETE`-запроса. Он автоматически управляет состоянием `loading`, проверяет контракты валидации запроса и ответа, применяет функцию трансформации к ответам, вызывает коллбэк `action` при успехе и безопасно обрабатывает ошибки.
21
25
 
22
26
  ```typescript
23
27
  import { useApiDelete } from '@dxtmisha/functional'
24
28
 
25
- const { loading, send } = useApiDelete(
26
- '/api/delete',
27
- (data) => console.log('Действие завершено:', data),
28
- (raw) => ({ ...raw, processed: true }),
29
- true,
30
- { cache: false }
31
- )
29
+ const { loading, send } = useApiDelete({
30
+ path: '/api/delete',
31
+ action: (data) => console.log('Действие завершено:', data),
32
+ transformation: (raw) => ({ ...raw, processed: true }),
33
+ toData: true,
34
+ options: { cache: false }
35
+ })
32
36
 
33
37
  const handleDelete = async () => {
34
38
  const result = await send({ id: 1 })