@ryuzaki13/react-foundation-lib 2.32.0 → 2.34.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 (36) hide show
  1. package/dist/analytical-table/index.js +2 -2
  2. package/dist/chunks/{formatters-CO40zvVB.js → formatters-4P9iq3wB.js} +385 -378
  3. package/dist/chunks/formatters-4P9iq3wB.js.map +1 -0
  4. package/dist/chunks/{formulas-Y0HOcFhe.js → formulas-BZtCqzBj.js} +71 -39
  5. package/dist/chunks/formulas-BZtCqzBj.js.map +1 -0
  6. package/dist/chunks/{validate-8URYKKly.js → validate-Drrm-CCz.js} +180 -171
  7. package/dist/chunks/validate-Drrm-CCz.js.map +1 -0
  8. package/dist/error-report/index.js +1 -1
  9. package/dist/excel/index.js +114 -112
  10. package/dist/excel/index.js.map +1 -1
  11. package/dist/excel/tableExport.d.ts.map +1 -1
  12. package/dist/formatters/index.js +3 -3
  13. package/dist/formatters/number/formatNumber.d.ts +2 -2
  14. package/dist/formatters/number/formatNumber.d.ts.map +1 -1
  15. package/dist/formatters/number/index.d.ts +1 -0
  16. package/dist/formatters/number/index.d.ts.map +1 -1
  17. package/dist/formatters/number/numberFormatConstants.d.ts +5 -0
  18. package/dist/formatters/number/numberFormatConstants.d.ts.map +1 -1
  19. package/dist/formatters/number/numberPresetNameConstants.d.ts +1 -0
  20. package/dist/formatters/number/numberPresetNameConstants.d.ts.map +1 -1
  21. package/dist/formatters/number/presets.d.ts +2 -1
  22. package/dist/formatters/number/presets.d.ts.map +1 -1
  23. package/dist/formatters/number/types.d.ts +3 -1
  24. package/dist/formatters/number/types.d.ts.map +1 -1
  25. package/dist/formulas/execute.d.ts +23 -1
  26. package/dist/formulas/execute.d.ts.map +1 -1
  27. package/dist/formulas/index.js +2 -2
  28. package/dist/formulas/types.d.ts +11 -1
  29. package/dist/formulas/types.d.ts.map +1 -1
  30. package/package.json +1 -1
  31. package/src/excel/README.mdx +12 -0
  32. package/src/formatters/number/README.mdx +41 -7
  33. package/src/formulas/README.mdx +111 -38
  34. package/dist/chunks/formatters-CO40zvVB.js.map +0 -1
  35. package/dist/chunks/formulas-Y0HOcFhe.js.map +0 -1
  36. package/dist/chunks/validate-8URYKKly.js.map +0 -1
@@ -74,6 +74,7 @@ const text = value === undefined ? "Некорректно" : formatNumber(value
74
74
  | `currency` | 0 | Денежное число без символа валюты |
75
75
  | `price` | 0 | Цена без символа валюты |
76
76
  | `percent` | 2 | Процентное число без автоматического умножения и знака `%` |
77
+ | `ratio-percent` | 2 | Доля с процентным масштабированием и знаком `%` |
77
78
  | `tonnage` | 1 | Тоннаж |
78
79
  | `compact-currency` | 0 | Компактное число, усечение |
79
80
  | `compact-currency-round` | 0 | Компактное число, округление |
@@ -97,6 +98,38 @@ import { DEFAULT_NUMBER_PRESET_NAMES, formatNumber } from "@ryuzaki13/react-foun
97
98
  formatNumber(1234.5, DEFAULT_NUMBER_PRESET_NAMES.decimal2);
98
99
  ```
99
100
 
101
+ ## Числовой процент и доля
102
+
103
+ `percent` и `formatNumberAsPercent` форматируют уже подготовленное число с двумя дробными знаками. `ratio-percent` принимает долю: числу `0.2` соответствует отображение `20,00%`. Передавать предварительно умноженное на 100 значение для этого preset не нужно.
104
+
105
+ ```ts
106
+ import {
107
+ DEFAULT_NUMBER_PRESET_NAMES,
108
+ NUMBER_PRESET_NAME_RATIO_PERCENT,
109
+ formatNumber,
110
+ formatNumberAsPercent
111
+ } from "@ryuzaki13/react-foundation-lib/formatters";
112
+
113
+ formatNumber(0.2, "percent"); // "0,20"
114
+ formatNumberAsPercent(0.2); // "0,20"
115
+ formatNumber(0.2, NUMBER_PRESET_NAME_RATIO_PERCENT); // "20,00%"
116
+ formatNumber(1, DEFAULT_NUMBER_PRESET_NAMES.ratioPercent); // "100,00%"
117
+ formatNumber(0, "ratio-percent"); // "0,00%"
118
+ ```
119
+
120
+ Число остаётся неизменным; процентное масштабирование относится только к представлению. Для formatter pipeline достаточно обычного `typedValueFormat` с `numberPresetName: "ratio-percent"`, в том числе у числовой колонки с целочисленным типом `int`. Смена preset не изменяет числовую семантику формул.
121
+
122
+ Необязательное поле `NumberFormatPreset.style` задаёт способ представления: отсутствие поля или `"decimal"` сохраняет обычный числовой формат, `"percent"` отображает долю со знаком `%`. Встроенный `ratio-percent` использует два дробных знака, собственный preset использует свой `decimals`:
123
+
124
+ ```ts
125
+ registerNumberPreset({ name: "ratio-3", style: "percent", decimals: 3 });
126
+ formatNumber(0.12345, "ratio-3"); // "12,345%"
127
+ ```
128
+
129
+ `style: "percent"` нельзя сочетать с `compact`: такая комбинация явно отклоняется. Существующие compact presets без marker сохраняют своё поведение.
130
+
131
+ При экспорте через `createTableExcelColumn` из `/excel` этот style создаёт native percentage mask с точностью preset. В строку книги передаётся исходное число `0.2`, а Excel отображает процент. Готовую строку `"20%"` или число `20` вместо доли передавать не следует. Формат старого `percent` остаётся обычным числовым.
132
+
100
133
  ## `formatNumber(value, presetOrName)`
101
134
 
102
135
  ```ts
@@ -109,7 +142,7 @@ function formatNumber(value: unknown, presetOrName: string | NumberFormatPreset)
109
142
  2. вызывает `Number(value)`;
110
143
  3. для `NaN` и бесконечности возвращает `"0"`;
111
144
  4. находит preset по имени или использует переданный объект;
112
- 5. округляет и форматирует число;
145
+ 5. округляет и форматирует число с учётом выбранного `style`;
113
146
  6. применяет compact-семантику, если она задана.
114
147
 
115
148
  ```ts
@@ -175,7 +208,7 @@ formatNumberAsCurrency(1250); // "1 250", без ₽
175
208
  formatNumberAsPercent(12.5); // "12,50", без %
176
209
  ```
177
210
 
178
- Если нужен суффикс, добавляйте его на UI-уровне или используйте специализированный модуль единиц измерения.
211
+ Для доли со знаком `%` используйте `ratio-percent`. Другие суффиксы добавляйте на UI-уровне или используйте специализированный модуль единиц измерения.
179
212
 
180
213
  ## Wrappers `OrEmpty`
181
214
 
@@ -388,7 +421,7 @@ formatNumber(1234.5, "accounting-2"); // "1 234,50"
388
421
 
389
422
  Регистрация глобальна для текущего экземпляра модуля. Выполняйте её один раз при старте приложения до компиляции formatter pipeline.
390
423
 
391
- Имя не trim-ится и поля не валидируются. Передавайте непустое устойчивое имя, не меняйте встроенные presets без явной необходимости и проверяйте числовые параметры.
424
+ Имя не trim-ится. Передавайте непустое устойчивое имя, не меняйте встроенные presets без явной необходимости и проверяйте числовые параметры. Сочетание `style: "percent"` с `compact` не поддерживается и отклоняется при регистрации или разрешении preset.
392
425
 
393
426
  ### `resetNumberPresets()`
394
427
 
@@ -426,7 +459,7 @@ formatNumber(1234567.89, {
426
459
 
427
460
  Такой объект не попадает в реестр. Он полезен для локального стабильного правила; переиспользуемый формат лучше зарегистрировать централизованно.
428
461
 
429
- Параметры не валидируются. Используйте:
462
+ Числовые параметры автоматически не валидируются. Используйте:
430
463
 
431
464
  - `decimals` — целое неотрицательное число в диапазоне, допустимом `Intl.NumberFormat`;
432
465
  - `groupingSize` — положительное целое число;
@@ -450,7 +483,7 @@ truncateNumber(123.789, -1); // 120
450
483
 
451
484
  ## Кеш `Intl.NumberFormat`
452
485
 
453
- Модуль кеширует formatter по комбинации `decimals + grouping`, что важно для сотен ячеек таблицы.
486
+ Модуль кеширует formatter по комбинации `style + decimals + grouping`, что важно для сотен ячеек таблицы. Числовой и процентный режимы не используют один formatter даже при одинаковой точности.
454
487
 
455
488
  ```ts
456
489
  clearFormatCache();
@@ -506,7 +539,7 @@ const text = parsed === undefined ? "—" : formatNumber(parsed, "decimal-2");
506
539
 
507
540
  ### Считать `percent` математическим процентом
508
541
 
509
- Preset не умножает `0.25` на 100 и не добавляет `%`. Он выведет `0,25`.
542
+ Preset не умножает `0.25` на 100 и не добавляет `%`. Он выведет `0,25`. Для отображения доли как `25,00%` выбирайте `ratio-percent`.
510
543
 
511
544
  ### Ожидать валютный символ
512
545
 
@@ -529,7 +562,7 @@ Preset не умножает `0.25` на 100 и не добавляет `%`. О
529
562
  | Ноль как пустое | все перечисленные wrappers с суффиксом `OrEmpty` |
530
563
  | Парсинг | `toFiniteNumber`, `parseNumber`, `isPositiveValue`, `toPositiveInteger` |
531
564
  | Проверка нуля | `isZeroValue` |
532
- | Presets | `DEFAULT_NUMBER_PRESET_NAMES`, `NUMBER_FORMAT_DEFAULTS`, `getNumberPreset`, `getNumberPresetNames`, `registerNumberPreset`, `resetNumberPresets` |
565
+ | Presets | `DEFAULT_NUMBER_PRESET_NAMES`, `NUMBER_PRESET_NAME_RATIO_PERCENT`, `NUMBER_FORMAT_DEFAULTS`, `getNumberPreset`, `getNumberPresetNames`, `registerNumberPreset`, `resetNumberPresets` |
533
566
  | Низкоуровневое | `truncateNumber`, `clearFormatCache` |
534
567
  | Типы | `NumberFormatPreset`, `NumberFormatPresetConfig`, `NumberFormatCompactOptions`, `NumberFormatCompactUnit`, `NumberFormatCompactRoundingMode` |
535
568
 
@@ -540,3 +573,4 @@ Preset не умножает `0.25` на 100 и не добавляет `%`. О
540
573
  - [Обзор `formatters`](../README.mdx)
541
574
  - [Строковая нормализация](../strings/README.mdx)
542
575
  - [Formatter pipeline](../pipeline/README.mdx)
576
+ - [Excel](../../excel/README.mdx)
@@ -6,7 +6,7 @@ import { Meta } from "@storybook/addon-docs/blocks";
6
6
 
7
7
  Модуль `@ryuzaki13/react-foundation-lib/formulas` предоставляет безопасную инфраструктуру для заранее написанных клиентских формул таблицы.
8
8
 
9
- Формула получает значения полей текущей строки и числовые константы, выполняет синхронный расчёт и возвращает конечное JavaScript-число. Например, она может вычислить сумму, разницу, отношение или процент для calculated-колонки.
9
+ Формула получает значения полей текущей строки и числовые константы либо заранее подготовленные host-приложением позиции, выполняет синхронный расчёт и возвращает конечное JavaScript-число. Например, она может вычислить сумму, разницу, отношение или процент для calculated-колонки.
10
10
 
11
11
  ```text
12
12
  данные строки + упорядоченные зависимости
@@ -30,6 +30,7 @@ import { Meta } from "@storybook/addon-docs/blocks";
30
30
  - [Чтение активного реестра](#чтение-активного-реестра)
31
31
  - [Выполнение формулы](#выполнение-формулы)
32
32
  - [Предварительная компиляция](#предварительная-компиляция)
33
+ - [Заранее разрешённые аргументы](#заранее-разрешённые-аргументы)
33
34
  - [Валидация зависимостей](#валидация-зависимостей)
34
35
  - [Интеграция с formatter pipeline](#интеграция-с-formatter-pipeline)
35
36
  - [Отличие от row-based formatter](#отличие-от-row-based-formatter)
@@ -50,6 +51,7 @@ import { Meta } from "@storybook/addon-docs/blocks";
50
51
  - хранит один активный реестр в текущем экземпляре модуля;
51
52
  - выполняет формулы без выбрасывания их runtime-ошибок наружу;
52
53
  - компилирует formula + keys в переиспользуемый executor;
54
+ - исполняет ту же зарегистрированную функцию над готовыми позиционными значениями без промежуточных полей строки;
53
55
  - проверяет существование формулы и корректность выбранных dependencies;
54
56
  - сообщает, какие dependency indexes реально использовала формула на тестовых данных.
55
57
 
@@ -68,7 +70,7 @@ import { Meta } from "@storybook/addon-docs/blocks";
68
70
 
69
71
  Host-приложение владеет прикладными `TableFormulaDefinition`: оно объявляет их в коде, тестирует, собирает в реестр и устанавливает на старте приложения.
70
72
 
71
- Сериализуемая конфигурация колонки хранит только стабильный `formulaId` и ordered dependencies. Реальная функция остаётся доверенным кодом приложения.
73
+ В row-only API сериализуемая конфигурация колонки хранит стабильный `formulaId` и ordered dependencies. Реальная функция остаётся доверенным кодом приложения.
72
74
 
73
75
  ## Импорт
74
76
 
@@ -77,16 +79,21 @@ Host-приложение владеет прикладными `TableFormulaDef
77
79
  ```ts
78
80
  import {
79
81
  compileTableFormula,
82
+ compileTableFormulaWithResolvedArguments,
80
83
  configureTableFormulaRegistry,
81
84
  createTableFormulaRegistry,
82
85
  executeTableFormula,
86
+ executeTableFormulaWithResolvedArguments,
83
87
  getTableFormulaById,
84
88
  getTableFormulaList,
85
89
  formatTableFormulaExpression,
86
- validateTableFormulaDependencies
90
+ validateTableFormulaDependencies,
91
+ type TableFormulaDefinition,
92
+ type TableFormulaExecutionResult,
93
+ type TableFormulaRegistry,
94
+ type TableFormulaResolvedArgument,
95
+ type TableFormulaResolvedExecutor
87
96
  } from "@ryuzaki13/react-foundation-lib/formulas";
88
-
89
- import type { TableFormulaDefinition, TableFormulaExecutionResult, TableFormulaRegistry } from "@ryuzaki13/react-foundation-lib/formulas";
90
97
  ```
91
98
 
92
99
  Корневой импорт пакета и private imports из исходников не поддерживаются:
@@ -365,7 +372,7 @@ interface TableFormulaContext {
365
372
 
366
373
  ### `ctx.key(index)`
367
374
 
368
- Возвращает id dependency по индексу:
375
+ В row-only API возвращает id dependency по индексу:
369
376
 
370
377
  ```ts
371
378
  // keys = ["planned", "actual"]
@@ -380,6 +387,8 @@ ctx.key(1.5); // undefined
380
387
 
381
388
  Пустая строка технически может вернуться из `key`, если она была передана в `keys`, но `value` и `num` считают пустой key отсутствующим. Используйте только непустые dependency ids.
382
389
 
390
+ Для [заранее разрешённых аргументов](#заранее-разрешённые-аргументы) key передаёт host; он не используется для поиска значения в строке.
391
+
383
392
  ### `ctx.value(index)`
384
393
 
385
394
  Возвращает исходное значение без преобразования:
@@ -389,7 +398,7 @@ ctx.key(1.5); // undefined
389
398
  ctx.value(1); // "25"
390
399
  ```
391
400
 
392
- Для константы возвращается непосредственно её числовое значение. Для неправильного индекса, пустого key или отсутствующего свойства возвращается `undefined`.
401
+ В row-only API для константы возвращается непосредственно её числовое значение. Для неправильного индекса, пустого key или отсутствующего свойства возвращается `undefined`. Для готовых позиций действуют [правила разрешённых аргументов](#заранее-разрешённые-аргументы).
393
402
 
394
403
  Используйте `value`, когда нужно отличать отсутствующее значение от нуля или применять собственный parser:
395
404
 
@@ -809,9 +818,69 @@ if (compiled.ok) {
809
818
 
810
819
  ### Синхронность и повторный вход
811
820
 
812
- Compiled executor переиспользует один context с изменяемой внутренней ссылкой на `rowData`. Это безопасно для обычной синхронной формулы.
821
+ Executor `compileTableFormula` переиспользует один context с изменяемой внутренней ссылкой на `rowData`. Это безопасно для обычной синхронной формулы.
822
+
823
+ Не делайте formula `async`, не сохраняйте `ctx` во внешнем state и не запускайте тот же row-only executor рекурсивно из formula. Такой код нарушает lifecycle переиспользуемого context. Отдельный контракт повторного входа для готовых позиций описан ниже.
824
+
825
+ ## Заранее разрешённые аргументы
826
+
827
+ Когда значения относятся к разным строкам или вычисляются host-приложением, передайте их в позициях непосредственно. Используются существующие `TableFormulaDefinition`, registry и методы `ctx.key`, `ctx.value`, `ctx.num`; новую арифметическую функцию для другого источника писать не требуется.
828
+
829
+ ```ts
830
+ type TableFormulaResolvedArgument = {
831
+ readonly value: unknown;
832
+ readonly key?: string;
833
+ };
834
+
835
+ type TableFormulaResolvedExecutor = (resolvedArguments: readonly TableFormulaResolvedArgument[]) => TableFormulaExecutionResult;
836
+ ```
837
+
838
+ ### Подготовка и выполнение
839
+
840
+ Реестр из быстрого старта уже содержит `sum`. Host получает значения до вызова runtime и сохраняет нужный порядок:
841
+
842
+ ```ts
843
+ import {
844
+ compileTableFormulaWithResolvedArguments,
845
+ executeTableFormulaWithResolvedArguments,
846
+ type TableFormulaResolvedArgument
847
+ } from "@ryuzaki13/react-foundation-lib/formulas";
848
+
849
+ const resolvedArguments: readonly TableFormulaResolvedArgument[] = [
850
+ { value: 20, key: "amount" }, // Поле текущей строки.
851
+ { value: 100 } // Уже полученное host-ом значение другой строки.
852
+ ];
853
+
854
+ const result = executeTableFormulaWithResolvedArguments({ formulaId: "sum", arguments: resolvedArguments });
855
+ // result: { ok: true, value: 120 }
856
+
857
+ const compiled = compileTableFormulaWithResolvedArguments({ formulaId: "sum" });
858
+
859
+ if (compiled.ok) {
860
+ const first = compiled.execute(resolvedArguments);
861
+ const second = compiled.execute([{ value: 30, key: "amount" }, { value: 200 }]);
862
+ // first.value === 120, second.value === 230 при успешном результате.
863
+ }
864
+ ```
865
+
866
+ Compile result содержит либо `ok: true` и `execute: TableFormulaResolvedExecutor`, либо `ok: false, reason: "formula_not_found"`. Массив передаётся при каждом execute, а не при compile. Для разового вычисления `executeTableFormulaWithResolvedArguments` выполняет compile и один вызов executor.
867
+
868
+ ### Значения, ключи и границы
869
+
870
+ - `value(index)` возвращает переданный `value` буквально, включая `null`, `undefined`, число или числовую строку. Значение не ищется в `rowData`; `key` не влияет на его чтение.
871
+ - Host задаёт `key` только для поля текущей строки. Для константы и внешнего источника его опускают, поэтому `key(index)` возвращает `undefined`. Не создавайте фиктивные ID вроде `TOTAL:Amount`.
872
+ - Порядок и повторы сохраняются. Для отрицательного, нецелого или вышедшего за массив индекса `key()` и `value()` возвращают `undefined`, `num()` — `0`.
873
+ - `num()` использует [действующее числовое преобразование](#числовое-преобразование-ctxnum). Исключение преобразования даёт `runtime_error`, а не успешный ноль.
874
+ - Каждая позиция содержит собственное поле `value`: `{ value: undefined }` корректен, дырка массива или запись без `value` дают `runtime_error`. Ошибка подготовки не подменяется временным нулём.
875
+ - Используется существующий `TableFormulaExecutionResult`: не конечный результат формулы даёт `invalid_result`, исключение — `runtime_error`. Значения и текст исключения не добавляются в результат ошибки.
876
+
877
+ ### Время жизни и ответственность host
878
+
879
+ Compiled executor сохраняет зарегистрированную функцию без массива аргументов. Контекст создаётся для отдельного синхронного вызова, поэтому вложенное выполнение того же executor не подменяет значения внешнего или следующего вызова. Входные массивы и записи не изменяются; значения не нормализуются и не копируются глубоко. Формулы остаются чистыми и синхронными; `ctx` нельзя сохранять для чтения после завершения вызова.
880
+
881
+ Host владеет сериализуемой ссылкой на источник, её доступностью, загрузкой, выбором исходного или вычисленного значения и проверкой циклов. Для ожидания данных он может явно подготовить `{ value: 0 }`, сохраняя состояние загрузки и диагностику отдельно. Runtime не получает DataSource callbacks и не разрешает ИТОГО или родителя самостоятельно.
813
882
 
814
- Не делайте formula `async`, не сохраняйте `ctx` во внешнем state и не запускайте тот же executor рекурсивно из formula. Такой код нарушает lifecycle переиспользуемого context.
883
+ `TableFormulaDependency`, row-only compile/execute, validator зависимостей, formatter выражения и formatter pipeline сохраняют свои контракты. `validateTableFormulaDependencies` не проверяет адреса внешних источников, а `formatTableFormulaExpression` не строит для них scoped preview. Готовые позиции — вход текущего выполнения, а не новый формат сохранённой конфигурации.
815
884
 
816
885
  ## Валидация зависимостей
817
886
 
@@ -862,7 +931,7 @@ Validator:
862
931
  | ------------------------------- | ----------------------------------------------------------- |
863
932
  | `formula_not_found` | Formula id отсутствует в registry |
864
933
  | `dependency_not_available` | Dependency id отсутствует среди доступных колонок |
865
- | `invalid_constant` | Константа не содержит конечное числовое значение |
934
+ | `invalid_constant` | Константа не содержит конечное числовое значение |
866
935
  | `dependency_index_out_of_range` | Formula прочитала index, для которого dependency не передан |
867
936
 
868
937
  ### Warnings
@@ -1165,7 +1234,7 @@ expect(
1165
1234
  быстрее: compileTableFormula один раз → execute(rowData) для каждой строки
1166
1235
  ```
1167
1236
 
1168
- Compiled executor переиспользует context и не делает registry lookup на каждую строку.
1237
+ Executor `compileTableFormula` переиспользует context и не делает registry lookup на каждую строку. `compileTableFormulaWithResolvedArguments` также находит функцию один раз, но создаёт отдельный контекст на каждый вызов; значения host подготавливает перед execute.
1169
1238
 
1170
1239
  Formatter pipeline уже использует этот подход: runtime field компилируется на construction-stage.
1171
1240
 
@@ -1235,42 +1304,46 @@ Promise не является конечным number и даст `invalid_resul
1235
1304
 
1236
1305
  ### Runtime functions
1237
1306
 
1238
- | API | Назначение | Важное поведение |
1239
- | ---------------------------------- | -------------------------------- | ------------------------------------------------------- |
1240
- | `createTableFormulaContext` | Создать context вручную | Копирует keys, но не rowData; `num` использует `Number` |
1241
- | `createTableFormulaRegistry` | Собрать нормализованный registry | Бросает `Error` для пустого/повторного id |
1242
- | `configureTableFormulaRegistry` | Установить активный registry | Полностью заменяет module-level registry |
1243
- | `getTableFormulaList` | Получить ordered catalog | Возвращает тот же readonly list |
1244
- | `getTableFormulaById` | Найти definition | Trim id; `undefined` для пустого/неизвестного |
1245
- | `formatTableFormulaExpression` | Подставить ID в шаблон превью | Сохраняет незаполненные `$n`; не исполняет выражение |
1246
- | `compileTableFormula` | Подготовить reusable executor | Фиксирует formula и копирует keys |
1247
- | `executeTableFormula` | Compile + один execute | Возвращает controlled result, не бросает formula error |
1248
- | `validateTableFormulaDependencies` | Проверить mapping dependencies | Дважды исполняет formula на synthetic data |
1307
+ | API | Назначение | Важное поведение |
1308
+ | ------------------------------------------ | ------------------------------------ | ------------------------------------------------------- |
1309
+ | `createTableFormulaContext` | Создать context вручную | Копирует keys, но не rowData; `num` использует `Number` |
1310
+ | `createTableFormulaRegistry` | Собрать нормализованный registry | Бросает `Error` для пустого/повторного id |
1311
+ | `configureTableFormulaRegistry` | Установить активный registry | Полностью заменяет module-level registry |
1312
+ | `getTableFormulaList` | Получить ordered catalog | Возвращает тот же readonly list |
1313
+ | `getTableFormulaById` | Найти definition | Trim id; `undefined` для пустого/неизвестного |
1314
+ | `formatTableFormulaExpression` | Подставить ID в шаблон превью | Сохраняет незаполненные `$n`; не исполняет выражение |
1315
+ | `compileTableFormula` | Подготовить reusable executor | Фиксирует formula и копирует keys |
1316
+ | `executeTableFormula` | Compile + один execute | Возвращает controlled result, не бросает formula error |
1317
+ | `compileTableFormulaWithResolvedArguments` | Подготовить executor готовых позиций | Фиксирует функцию; аргументы передаются при execute |
1318
+ | `executeTableFormulaWithResolvedArguments` | Выполнить готовые позиции один раз | Использует тот же registry и execution result |
1319
+ | `validateTableFormulaDependencies` | Проверить mapping dependencies | Дважды исполняет formula на synthetic data |
1249
1320
 
1250
1321
  ### Публичные TypeScript-типы
1251
1322
 
1252
- | Тип | Назначение |
1253
- | ------------------------------------------ | ------------------------------------------ |
1254
- | `TableFormulaRowData` | Строка `Record<string, unknown>` |
1323
+ | Тип | Назначение |
1324
+ | ------------------------------------------ | ----------------------------------------------- |
1325
+ | `TableFormulaRowData` | Строка `Record<string, unknown>` |
1255
1326
  | `TableFormulaDependency` | ID поля либо объект конечной числовой константы |
1256
- | `TableFormulaContext` | Методы `key`, `value`, `num` |
1257
- | `TableFormulaFn` | Синхронная function `context → number` |
1258
- | `TableFormulaDefinition` | Metadata и function одной formula |
1259
- | `TableFormulaRegistry` | Readonly `list` + `byId` |
1260
- | `TableFormulaExecutionResult` | Success/error результат execute |
1261
- | `TableFormulaCompiledExecutor` | Переиспользуемый `(rowData) → result` |
1262
- | `TableFormulaValidationMessage` | `{ code, message }` validation diagnostics |
1263
- | `TableFormulaDependenciesValidationResult` | Errors, warnings и usage dependencies |
1327
+ | `TableFormulaContext` | Методы `key`, `value`, `num` |
1328
+ | `TableFormulaFn` | Синхронная function `context → number` |
1329
+ | `TableFormulaDefinition` | Metadata и function одной formula |
1330
+ | `TableFormulaRegistry` | Readonly `list` + `byId` |
1331
+ | `TableFormulaExecutionResult` | Success/error результат execute |
1332
+ | `TableFormulaCompiledExecutor` | Переиспользуемый `(rowData) → result` |
1333
+ | `TableFormulaResolvedArgument` | Готовое `value` и optional `key` позиции |
1334
+ | `TableFormulaResolvedExecutor` | Переиспользуемый `(resolvedArguments) → result` |
1335
+ | `TableFormulaValidationMessage` | `{ code, message }` validation diagnostics |
1336
+ | `TableFormulaDependenciesValidationResult` | Errors, warnings и usage dependencies |
1264
1337
 
1265
1338
  `ValidationCode`, instrumentation type и compile-result type не экспортируются как именованные публичные типы. Их конкретные значения доступны через публичные function signatures и unions, описанные выше.
1266
1339
 
1267
1340
  ### Причины execution error
1268
1341
 
1269
- | Reason | Значение |
1270
- | ------------------- | --------------------------------------- |
1271
- | `formula_not_found` | Formula отсутствует в активном registry |
1272
- | `invalid_result` | Function вернула не конечный number |
1273
- | `runtime_error` | Function выбросила исключение |
1342
+ | Reason | Значение |
1343
+ | ------------------- | --------------------------------------------------------------------- |
1344
+ | `formula_not_found` | Formula отсутствует в активном registry |
1345
+ | `invalid_result` | Function вернула не конечный number |
1346
+ | `runtime_error` | Некорректные готовые позиции или исключение выполнения/преобразования |
1274
1347
 
1275
1348
  ### Validation codes
1276
1349