intelicoreact 2.0.5 → 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.
@@ -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: string;
5
- maxItemSizeBytes: number;
6
- error: string | null;
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>;
@@ -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
+ }
@@ -19,7 +19,7 @@ export interface IFormElementProps extends IUniProps {
19
19
  placeholder?: string;
20
20
  mask?: string;
21
21
  alert?: {
22
- message: string;
22
+ message: string | ReactNode;
23
23
  variant: 'info' | 'warning' | 'error' | 'success';
24
24
  noDismiss?: boolean;
25
25
  };
@@ -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) => Promise.resolve({
95
- ok: false,
96
- status: 0,
97
- statusText: response,
98
- request: item
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.path === response.request.path);
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);