intelicoreact 2.0.4 → 2.0.6
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/Atomic/FormElements/CheckboxInput/CheckboxInput.interface.d.ts +2 -1
- package/dist/Atomic/FormElements/FileLoaderDescription/FileLoaderDescription.interface.d.ts +3 -3
- package/dist/Atomic/FormElements/Switcher/Switcher.interface.d.ts +2 -1
- package/dist/Atomic/UI/AccordionText/AccordionText.interface.d.ts +13 -0
- package/dist/Atomic/UI/Alert/Alert.interface.d.ts +1 -1
- package/dist/Atomic/UI/Modal/index.d.ts +3 -0
- package/dist/Functions/sdk/runtime-sdk/client.d.ts +19 -0
- package/dist/Functions/sdk/runtime-sdk/config.d.ts +32 -0
- package/dist/Functions/sdk/runtime-sdk/index.d.ts +3 -0
- package/dist/Functions/sdk/runtime-sdk/queue.d.ts +70 -0
- package/dist/Functions/sdk/runtime-sdk/transport.d.ts +41 -0
- package/dist/Functions/sdk/runtime-sdk/types.d.ts +84 -0
- package/dist/Molecular/FormElement/FormElement.interface.d.ts +1 -1
- package/dist/Molecular/FormWithDependOn/FormWithDependOn.interface.d.ts +99 -0
- package/dist/classes.cjs +10 -8
- package/dist/classes.cjs.map +2 -2
- package/dist/classes.js +10 -8
- package/dist/classes.js.map +2 -2
- package/dist/form.cjs +1853 -1779
- package/dist/form.cjs.map +4 -4
- package/dist/form.d.ts +42 -17
- package/dist/form.js +1848 -1774
- package/dist/form.js.map +4 -4
- package/dist/index.cjs +2229 -2139
- package/dist/index.cjs.map +4 -4
- package/dist/index.js +2041 -1951
- package/dist/index.js.map +4 -4
- package/dist/sdk.cjs +451 -0
- package/dist/sdk.cjs.map +7 -0
- package/dist/sdk.d.ts +5 -0
- package/dist/sdk.js +429 -0
- package/dist/sdk.js.map +7 -0
- package/dist/ui.cjs +398 -366
- package/dist/ui.cjs.map +4 -4
- package/dist/ui.d.ts +11 -7
- package/dist/ui.js +270 -238
- package/dist/ui.js.map +4 -4
- package/package.json +11 -1
- package/sdk/package.json +5 -0
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type React from 'react';
|
|
2
|
+
import type { ReactNode } from 'react';
|
|
2
3
|
import type { IUniProps } from '../../../types/base.interface';
|
|
3
4
|
export interface ICheckboxInputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'value' | 'onChange' | 'id'>, IUniProps {
|
|
4
|
-
label: string;
|
|
5
|
+
label: string | ReactNode;
|
|
5
6
|
id?: string | number;
|
|
6
7
|
value?: boolean;
|
|
7
8
|
onChange?: (value: boolean, event: React.ChangeEvent<HTMLInputElement>) => void;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export interface IFile {
|
|
2
2
|
id?: string | number;
|
|
3
3
|
value: string;
|
|
4
|
-
base64
|
|
5
|
-
maxItemSizeBytes
|
|
6
|
-
error
|
|
4
|
+
base64?: string;
|
|
5
|
+
maxItemSizeBytes?: number;
|
|
6
|
+
error?: string | null;
|
|
7
7
|
outerError?: string | null | boolean;
|
|
8
8
|
isRequired?: boolean;
|
|
9
9
|
accept?: string;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import type React from 'react';
|
|
2
|
+
import type { ReactNode } from 'react';
|
|
2
3
|
import type { IUniProps } from '../../../types/base.interface';
|
|
3
4
|
export interface ISwitcherProps extends IUniProps {
|
|
4
5
|
isLabelBold?: boolean;
|
|
5
6
|
disabled?: boolean;
|
|
6
7
|
isIncludeOuterStyles?: boolean;
|
|
7
|
-
label?: string;
|
|
8
|
+
label?: string | ReactNode;
|
|
8
9
|
className?: string;
|
|
9
10
|
isActive?: boolean;
|
|
10
11
|
hint?: React.ReactNode;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Props компонента `<AccordionText>`. Раньше тип default-export получал
|
|
4
|
+
* TS-inference из `.js`, что давало `text: string` (потерявшийся ReactNode).
|
|
5
|
+
* Этот interface восстанавливает type-safe usage с поддержкой JSX в `text`.
|
|
6
|
+
*/
|
|
7
|
+
export interface IAccordionTextProps {
|
|
8
|
+
isDefaultOpen?: boolean;
|
|
9
|
+
isOuterOpen?: boolean;
|
|
10
|
+
className?: string;
|
|
11
|
+
text?: string | ReactNode;
|
|
12
|
+
shortText?: string | ReactNode | null;
|
|
13
|
+
}
|
|
@@ -2,7 +2,7 @@ import type { CSSProperties, ReactNode } from 'react';
|
|
|
2
2
|
import type { IUniProps } from '../../../types/base.interface';
|
|
3
3
|
type TButtonVariant = 'primary' | 'ellipse-apply' | 'ellipse-cancel' | string;
|
|
4
4
|
export interface IAlertProps extends IUniProps {
|
|
5
|
-
message?: string;
|
|
5
|
+
message?: string | ReactNode;
|
|
6
6
|
icon?: ReactNode;
|
|
7
7
|
iconDynamicKey?: string;
|
|
8
8
|
iconDynamicProps?: Record<string, any>;
|
|
@@ -4,6 +4,9 @@ import { EVENTS } from './partials/_constants';
|
|
|
4
4
|
import { dispatchEventForModalManagement } from './partials/_utils';
|
|
5
5
|
export type { IModalFooterProps, IModalHOCProps, IModalProps, IModalTitleProps } from './Modal.interface';
|
|
6
6
|
export { Modal, ModalHOC };
|
|
7
|
+
export { default as ModalFooter } from './partials/ModalFooter';
|
|
8
|
+
export { default as ModalTitle } from './partials/ModalTitle';
|
|
9
|
+
export { default as useMobileModal } from './partials/useMobileModal';
|
|
7
10
|
export { EVENTS };
|
|
8
11
|
export { dispatchEventForModalManagement };
|
|
9
12
|
export default Modal;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { RuntimeClient, RuntimeClientConfig } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Создаёт и возвращает singleton-инстанс клиента для работы с
|
|
4
|
+
* runtime-эндпоинтами MCP Contract Intelligence сервера.
|
|
5
|
+
*
|
|
6
|
+
* Вызывается один раз при инициализации фронта. Полученный инстанс
|
|
7
|
+
* используется во всём приложении для отправки runtime-логов (REST/WS)
|
|
8
|
+
* и удаления накопленных логов на сервере.
|
|
9
|
+
*
|
|
10
|
+
* Внутри:
|
|
11
|
+
* - нормализует конфиг и выставляет оптимизированные дефолты
|
|
12
|
+
* - поднимает внутреннюю очередь-батчер (interval + size triggers)
|
|
13
|
+
* - регистрирует `pagehide` / `beforeunload` listener'ы для
|
|
14
|
+
* отправки последнего батча через `navigator.sendBeacon`
|
|
15
|
+
*
|
|
16
|
+
* SDK не бросает ошибки наружу при проблемах сети/лимитов —
|
|
17
|
+
* всё уходит в `logger` и `onError`, чтобы не ронять прод.
|
|
18
|
+
*/
|
|
19
|
+
export declare function createRuntimeClient(rawConfig: RuntimeClientConfig): RuntimeClient;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { ResolvedConfig, RuntimeClientConfig } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Нормализует пользовательский конфиг в `ResolvedConfig` со всеми
|
|
4
|
+
* дефолтами и валидацией.
|
|
5
|
+
*
|
|
6
|
+
* Что делает:
|
|
7
|
+
* - проверяет обязательные поля (`baseUrl`)
|
|
8
|
+
* - обрезает хвостовые слэши у `baseUrl`
|
|
9
|
+
* - подставляет `fetch` из глобалов или из `config.fetchImpl`
|
|
10
|
+
* (нужен для SSR/Node-тестов, где `globalThis.fetch` может отсутствовать)
|
|
11
|
+
* - применяет оптимизированные дефолты и clamp на разумные границы,
|
|
12
|
+
* чтобы кривые значения (0, Infinity, отрицательные) не ломали SDK
|
|
13
|
+
* - выбирает logger: явный → передан, иначе console-логгер в debug,
|
|
14
|
+
* иначе no-op
|
|
15
|
+
*
|
|
16
|
+
* Бросает `Error` только при фатально неправильной конфигурации.
|
|
17
|
+
*/
|
|
18
|
+
export declare function resolveConfig(config: RuntimeClientConfig): ResolvedConfig;
|
|
19
|
+
/**
|
|
20
|
+
* Собирает финальный набор HTTP-заголовков для запроса.
|
|
21
|
+
*
|
|
22
|
+
* Приоритет (поздний перезатирает ранний):
|
|
23
|
+
* 1. `Content-Type: application/json` по умолчанию
|
|
24
|
+
* 2. `config.headers` из конфига SDK
|
|
25
|
+
* 3. `extra` — точечные заголовки конкретного запроса
|
|
26
|
+
* 4. `X-API-Key` из `config.apiKey`, если задан — всегда поверх всего,
|
|
27
|
+
* чтобы его нельзя было случайно переопределить через `headers`
|
|
28
|
+
*
|
|
29
|
+
* Сервер использует `X-API-Key` как bucket-key для rate-limiter'а
|
|
30
|
+
* (см. `ingestion-rate-limit.guard.ts`). Это **не** токен авторизации.
|
|
31
|
+
*/
|
|
32
|
+
export declare function buildHeaders(config: ResolvedConfig, extra?: Record<string, string>): Record<string, string>;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { createRuntimeClient } from './client';
|
|
2
|
+
export { HttpError } from './transport';
|
|
3
|
+
export type { BatchIngestRequest, BatchIngestResponse, DeleteLogsFilter, DeleteLogsResponse, Logger, RestRuntimeLog, RuntimeClient, RuntimeClientConfig, RuntimeLog, WsRuntimeLog, } from './types';
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { ResolvedConfig, RuntimeLog } from './types';
|
|
2
|
+
export declare class BatchQueue {
|
|
3
|
+
private readonly config;
|
|
4
|
+
private buffer;
|
|
5
|
+
private timer;
|
|
6
|
+
private inflight;
|
|
7
|
+
private destroyed;
|
|
8
|
+
/**
|
|
9
|
+
* Создаёт очередь и, если `flushIntervalMs > 0`, запускает
|
|
10
|
+
* периодический таймер флаша. Таймер будет тикать до тех пор,
|
|
11
|
+
* пока не вызовут `destroy()`.
|
|
12
|
+
*/
|
|
13
|
+
constructor(config: ResolvedConfig);
|
|
14
|
+
/**
|
|
15
|
+
* Текущее количество событий в буфере (ещё не отправленных).
|
|
16
|
+
* Полезно для метрик/дебага.
|
|
17
|
+
*/
|
|
18
|
+
size(): number;
|
|
19
|
+
/**
|
|
20
|
+
* Добавить события в буфер.
|
|
21
|
+
*
|
|
22
|
+
* Триггеры автоматического флаша:
|
|
23
|
+
* - буфер достиг `batchSize` → сразу уходит HTTP-запрос
|
|
24
|
+
* - буфер превысил `maxQueueSize` → лишние **старые** события
|
|
25
|
+
* дропаются (FIFO), чтобы не раздувать память при сбое сети
|
|
26
|
+
*
|
|
27
|
+
* После `destroy()` вызов игнорируется.
|
|
28
|
+
*/
|
|
29
|
+
enqueue(logs: RuntimeLog[]): void;
|
|
30
|
+
/**
|
|
31
|
+
* Забрать всё из буфера и отправить одним батчем в
|
|
32
|
+
* `POST /api/runtime/ingest`.
|
|
33
|
+
*
|
|
34
|
+
* Если уже есть активный in-flight запрос — возвращаем его же
|
|
35
|
+
* промис (защита от параллельных флашей по таймеру и по размеру).
|
|
36
|
+
*
|
|
37
|
+
* Ошибки HTTP/сети сюда не всплывают — они проглатываются
|
|
38
|
+
* после всех retry-попыток и логируются как 'error'. Дроп
|
|
39
|
+
* целого батча при окончательном фейле — осознанный компромисс:
|
|
40
|
+
* лучше потерять часть телеметрии, чем заблокировать очередь.
|
|
41
|
+
*/
|
|
42
|
+
flush(): Promise<void>;
|
|
43
|
+
/**
|
|
44
|
+
* Отправить буфер через `navigator.sendBeacon` при закрытии вкладки.
|
|
45
|
+
*
|
|
46
|
+
* В отличие от обычного `flush()`:
|
|
47
|
+
* - fire-and-forget: нет ответа и нет retry
|
|
48
|
+
* - браузер гарантирует доставку даже после того как страница
|
|
49
|
+
* уже уничтожается (unload / pagehide)
|
|
50
|
+
* - нет заголовка `X-API-Key` (sendBeacon не даёт менять headers,
|
|
51
|
+
* но `Content-Type` нам выставляет сам тип Blob)
|
|
52
|
+
*
|
|
53
|
+
* Возвращает `true` если браузер принял пачку в свою очередь,
|
|
54
|
+
* `false` при отсутствии API или отказе (например слишком
|
|
55
|
+
* большой payload — лимит обычно 64 КБ).
|
|
56
|
+
*/
|
|
57
|
+
flushBeacon(): boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Остановить очередь и освободить ресурсы.
|
|
60
|
+
*
|
|
61
|
+
* Чистит таймер флаша, обнуляет буфер, помечает инстанс
|
|
62
|
+
* уничтоженным — последующие `enqueue`/`flush`/`flushBeacon`
|
|
63
|
+
* становятся no-op. Идемпотентна.
|
|
64
|
+
*
|
|
65
|
+
* Важно: in-flight запрос, если он был запущен до `destroy`,
|
|
66
|
+
* не отменяется — он либо завершится штатно, либо по таймауту
|
|
67
|
+
* `requestTimeoutMs`.
|
|
68
|
+
*/
|
|
69
|
+
destroy(): void;
|
|
70
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { ResolvedConfig } from './types';
|
|
2
|
+
export declare class HttpError extends Error {
|
|
3
|
+
readonly status: number;
|
|
4
|
+
readonly body: string;
|
|
5
|
+
readonly retryAfterMs?: number | undefined;
|
|
6
|
+
constructor(status: number, body: string, retryAfterMs?: number | undefined);
|
|
7
|
+
}
|
|
8
|
+
interface RequestOptions {
|
|
9
|
+
method: 'POST' | 'DELETE' | 'GET';
|
|
10
|
+
path: string;
|
|
11
|
+
body?: unknown;
|
|
12
|
+
query?: Record<string, string>;
|
|
13
|
+
signal?: AbortSignal;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Однократный HTTP-запрос без retry-логики.
|
|
17
|
+
*
|
|
18
|
+
* Особенности:
|
|
19
|
+
* - таймаут через `AbortController`, дефолт 8 с
|
|
20
|
+
* - non-2xx ответ → `HttpError` с распарсенным `Retry-After`
|
|
21
|
+
* - поддерживает `application/json` и text-ответы
|
|
22
|
+
* - 204 No Content → резолв `undefined`
|
|
23
|
+
*
|
|
24
|
+
* Используется как строительный блок для `requestWithRetry`
|
|
25
|
+
* и для случаев, где retry не нужен (напр. программная отмена).
|
|
26
|
+
*/
|
|
27
|
+
export declare function request<T>(config: ResolvedConfig, options: RequestOptions): Promise<T>;
|
|
28
|
+
/**
|
|
29
|
+
* HTTP-запрос с экспоненциальным бэкоффом и уважением к `Retry-After`.
|
|
30
|
+
*
|
|
31
|
+
* Retry-стратегия:
|
|
32
|
+
* - 429 Too Many Requests → ждём `Retry-After` (секунды или HTTP-date)
|
|
33
|
+
* - 5xx → экспоненциальный бэкофф `300 * 2^attempt + jitter`, cap 10 с
|
|
34
|
+
* - `AbortError` / `TypeError` (сетевые) → тоже retry
|
|
35
|
+
* - 4xx кроме 429 → сразу финальный reject (чинить нечего)
|
|
36
|
+
*
|
|
37
|
+
* Каждая попытка (успех или нет) проходит через `logger` и `onError`
|
|
38
|
+
* с указанием `phase` — это даёт наблюдаемость без перехвата промиса.
|
|
39
|
+
*/
|
|
40
|
+
export declare function requestWithRetry<T>(config: ResolvedConfig, options: RequestOptions, phase: 'ingest' | 'delete'): Promise<T>;
|
|
41
|
+
export {};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
export interface RuntimeLogBase {
|
|
2
|
+
service: string;
|
|
3
|
+
status?: number;
|
|
4
|
+
response?: unknown;
|
|
5
|
+
payload?: unknown;
|
|
6
|
+
timestamp?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface RestRuntimeLog extends RuntimeLogBase {
|
|
9
|
+
type: 'rest';
|
|
10
|
+
path: string;
|
|
11
|
+
method: string;
|
|
12
|
+
}
|
|
13
|
+
export interface WsRuntimeLog extends RuntimeLogBase {
|
|
14
|
+
type: 'ws';
|
|
15
|
+
event: string;
|
|
16
|
+
}
|
|
17
|
+
export type RuntimeLog = RestRuntimeLog | WsRuntimeLog;
|
|
18
|
+
export interface BatchIngestRequest {
|
|
19
|
+
logs: RuntimeLog[];
|
|
20
|
+
}
|
|
21
|
+
export interface BatchIngestResponse {
|
|
22
|
+
accepted: number;
|
|
23
|
+
}
|
|
24
|
+
export type DeleteLogsFilter = {
|
|
25
|
+
service: string;
|
|
26
|
+
type: 'rest';
|
|
27
|
+
path: string;
|
|
28
|
+
method: string;
|
|
29
|
+
} | {
|
|
30
|
+
service: string;
|
|
31
|
+
type: 'ws';
|
|
32
|
+
event: string;
|
|
33
|
+
};
|
|
34
|
+
export interface DeleteLogsResponse {
|
|
35
|
+
deleted: number;
|
|
36
|
+
}
|
|
37
|
+
export type Logger = (level: 'debug' | 'warn' | 'error', message: string, meta?: unknown) => void;
|
|
38
|
+
export interface RuntimeClientConfig {
|
|
39
|
+
baseUrl: string;
|
|
40
|
+
apiKey?: string;
|
|
41
|
+
enabled?: boolean;
|
|
42
|
+
debug?: boolean;
|
|
43
|
+
batchSize?: number;
|
|
44
|
+
flushIntervalMs?: number;
|
|
45
|
+
maxQueueSize?: number;
|
|
46
|
+
maxRetries?: number;
|
|
47
|
+
requestTimeoutMs?: number;
|
|
48
|
+
flushOnUnload?: boolean;
|
|
49
|
+
fetchImpl?: typeof fetch;
|
|
50
|
+
logger?: Logger;
|
|
51
|
+
onError?: (error: unknown, context: {
|
|
52
|
+
phase: 'ingest' | 'delete';
|
|
53
|
+
attempt: number;
|
|
54
|
+
}) => void;
|
|
55
|
+
headers?: Record<string, string>;
|
|
56
|
+
}
|
|
57
|
+
export interface ResolvedConfig {
|
|
58
|
+
baseUrl: string;
|
|
59
|
+
apiKey?: string;
|
|
60
|
+
enabled: boolean;
|
|
61
|
+
debug: boolean;
|
|
62
|
+
batchSize: number;
|
|
63
|
+
flushIntervalMs: number;
|
|
64
|
+
maxQueueSize: number;
|
|
65
|
+
maxRetries: number;
|
|
66
|
+
requestTimeoutMs: number;
|
|
67
|
+
flushOnUnload: boolean;
|
|
68
|
+
fetchImpl: typeof fetch;
|
|
69
|
+
logger: Logger;
|
|
70
|
+
onError?: (error: unknown, context: {
|
|
71
|
+
phase: 'ingest' | 'delete';
|
|
72
|
+
attempt: number;
|
|
73
|
+
}) => void;
|
|
74
|
+
headers: Record<string, string>;
|
|
75
|
+
}
|
|
76
|
+
export interface RuntimeClient {
|
|
77
|
+
track: (log: RuntimeLog) => void;
|
|
78
|
+
trackMany: (logs: RuntimeLog[]) => void;
|
|
79
|
+
flush: () => Promise<void>;
|
|
80
|
+
deleteLogs: (filter: DeleteLogsFilter) => Promise<DeleteLogsResponse>;
|
|
81
|
+
isEnabled: () => boolean;
|
|
82
|
+
setEnabled: (enabled: boolean) => void;
|
|
83
|
+
destroy: () => void;
|
|
84
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import type { ReactElement, ReactNode, Ref } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Минимальная форма-поле, которое FormWithDependOn ожидает в массиве `form`.
|
|
4
|
+
* Реальные поля имеют больше свойств (зависят от типа), но эти три обязательны
|
|
5
|
+
* для работы dependOn-механики.
|
|
6
|
+
*/
|
|
7
|
+
export interface IFormWithDependOnField {
|
|
8
|
+
key: string;
|
|
9
|
+
value?: unknown;
|
|
10
|
+
dependOn?: unknown;
|
|
11
|
+
[extra: string]: unknown;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Аргумент `additionalOfOnChange` — необязательный объект с метаданными,
|
|
15
|
+
* который верхний onChange может пробросить вниз через DependOn-механику.
|
|
16
|
+
*/
|
|
17
|
+
export interface IFormWithDependOnAdditional {
|
|
18
|
+
updatedForm?: IFormWithDependOnField[];
|
|
19
|
+
isMakeChangesAnyway?: boolean;
|
|
20
|
+
isUseActualForm?: boolean;
|
|
21
|
+
[extra: string]: unknown;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Контекст, передаваемый в `getAnotherActions`. Содержит вспомогательные
|
|
25
|
+
* функции, которые можно вызывать из middleware-экшенов.
|
|
26
|
+
*/
|
|
27
|
+
export interface IFormWithDependOnActionsContext<TField extends IFormWithDependOnField = IFormWithDependOnField> {
|
|
28
|
+
setForm: (form: TField[]) => void;
|
|
29
|
+
assign: (changes: Partial<TField>, fieldKey: string) => void;
|
|
30
|
+
getActualForm: () => TField[];
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Сигнатура одного экшена в map'е, возвращаемом `getAnotherActions`.
|
|
34
|
+
* Может быть `all` (срабатывает на любое изменение) или `<fieldKey>`
|
|
35
|
+
* (только при изменении конкретного поля). Возвращаемое значение —
|
|
36
|
+
* частичные изменения, которые будут применены через `assign`.
|
|
37
|
+
*/
|
|
38
|
+
export type FormWithDependOnAction<TField extends IFormWithDependOnField = IFormWithDependOnField> = (params: {
|
|
39
|
+
newValue: unknown;
|
|
40
|
+
fieldKey: string;
|
|
41
|
+
propKey: string | undefined;
|
|
42
|
+
field: TField;
|
|
43
|
+
form: TField[];
|
|
44
|
+
additional: Record<string, unknown>;
|
|
45
|
+
}) => Partial<TField> | void;
|
|
46
|
+
export type FormWithDependOnActionsMap<TField extends IFormWithDependOnField = IFormWithDependOnField> = {
|
|
47
|
+
all?: FormWithDependOnAction<TField>;
|
|
48
|
+
[fieldKey: string]: FormWithDependOnAction<TField> | undefined;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Props компонента `<FormWithDependOn>`. Generic-параметр `TField` позволяет
|
|
52
|
+
* вызывающему коду указать конкретный shape поля и получить type-safe
|
|
53
|
+
* `onChange`, `renderField`, `getAnotherActions`.
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```tsx
|
|
57
|
+
* type MyField = IFormWithDependOnField & { type: 'text' | 'select' };
|
|
58
|
+
* <FormWithDependOn<MyField>
|
|
59
|
+
* form={fields}
|
|
60
|
+
* setForm={setFields}
|
|
61
|
+
* onChange={(value, key) => ...}
|
|
62
|
+
* renderField={(field) => <Input ... />}
|
|
63
|
+
* />
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
export interface IFormWithDependOnProps<TField extends IFormWithDependOnField = IFormWithDependOnField> {
|
|
67
|
+
form: TField[];
|
|
68
|
+
setForm: (form: TField[]) => void;
|
|
69
|
+
formId?: string;
|
|
70
|
+
/**
|
|
71
|
+
* Опциональный геттер актуальной формы (для асинхронных последовательных
|
|
72
|
+
* зависимостей). По умолчанию вернёт текущий `form` prop.
|
|
73
|
+
*
|
|
74
|
+
* @deprecated рекомендуется НЕ использовать — работает плохо в текущей
|
|
75
|
+
* реализации (см. JS-source TODO от автора либы).
|
|
76
|
+
*/
|
|
77
|
+
getActualForm?: () => TField[];
|
|
78
|
+
/** Главный обработчик изменения значения поля. */
|
|
79
|
+
onChange?: (newValue: unknown, fieldKey: string, propKey?: string, additionalOfOnChange?: IFormWithDependOnAdditional) => void;
|
|
80
|
+
/** Рендер одного поля. Receives field + bound onChange. */
|
|
81
|
+
renderField?: (field: TField, index: number) => ReactNode;
|
|
82
|
+
/**
|
|
83
|
+
* Фабрика map'а side-actions. Срабатывают после dependOn-обработки.
|
|
84
|
+
* Возвращаемые changes применяются через `assign`.
|
|
85
|
+
*/
|
|
86
|
+
getAnotherActions?: (ctx: IFormWithDependOnActionsContext<TField>) => FormWithDependOnActionsMap<TField>;
|
|
87
|
+
className?: string;
|
|
88
|
+
isInitializeByDependOn?: boolean;
|
|
89
|
+
isFormDisabled?: boolean;
|
|
90
|
+
typeOfUse?: 'default' | string;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Тип default-export компонента `FormWithDependOn`. Раньше тип default-export
|
|
94
|
+
* получал TS-inference из `.js` source'а и терял generic. Этот declaration
|
|
95
|
+
* восстанавливает generic для type-safe usage.
|
|
96
|
+
*/
|
|
97
|
+
export type FormWithDependOnComponent = <TField extends IFormWithDependOnField = IFormWithDependOnField>(props: IFormWithDependOnProps<TField> & {
|
|
98
|
+
ref?: Ref<unknown>;
|
|
99
|
+
}) => ReactElement | null;
|
package/dist/classes.cjs
CHANGED
|
@@ -91,12 +91,14 @@ var AbortableFetch = class {
|
|
|
91
91
|
response.request = item;
|
|
92
92
|
return response;
|
|
93
93
|
}).catch(
|
|
94
|
-
(response) =>
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
94
|
+
(response) => {
|
|
95
|
+
return Promise.resolve({
|
|
96
|
+
ok: false,
|
|
97
|
+
status: 0,
|
|
98
|
+
statusText: response,
|
|
99
|
+
request: item
|
|
100
|
+
});
|
|
101
|
+
}
|
|
100
102
|
);
|
|
101
103
|
if (this.#everyPromiseCallback && !item.isSkipEveryPromiseCallback)
|
|
102
104
|
request = request.then(
|
|
@@ -470,7 +472,7 @@ var AbortableFetch2 = class {
|
|
|
470
472
|
const abortController = new AbortController();
|
|
471
473
|
const addProps = (response, request) => {
|
|
472
474
|
response.request = request;
|
|
473
|
-
if (ABORTABLE_FETCH_CONTEXT.#isResponseAsObject) response.name = request.name;
|
|
475
|
+
if (ABORTABLE_FETCH_CONTEXT.#isResponseAsObject) response.name = getIsOnlyAnObject(request) ? request.name || "" : "";
|
|
474
476
|
return response;
|
|
475
477
|
};
|
|
476
478
|
let externalRequest = Promise.all(
|
|
@@ -792,7 +794,7 @@ async function getInstanceOfFetchSystem(isGetBody) {
|
|
|
792
794
|
everyPromiseCallback: async function everyPromiseCallback(response) {
|
|
793
795
|
const ABORTABLE_FETCH_INSTANCE = this;
|
|
794
796
|
if (!response.status) {
|
|
795
|
-
const request = ABORTABLE_FETCH_INSTANCE.requestInput.find((item) => item
|
|
797
|
+
const request = ABORTABLE_FETCH_INSTANCE.requestInput.find((item) => item?.path === response?.request?.path);
|
|
796
798
|
const isUseErrorToast = request?.mesageOptions?.isUseErrorToast;
|
|
797
799
|
if (isUseErrorToast) {
|
|
798
800
|
API_CONTEXT.sendMessage?.(API_CONTEXT.NO_INET, request.mesageOptions, response);
|