palistor 0.0.24 → 0.0.26

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 (278) hide show
  1. package/README.md +574 -542
  2. package/README.ru.md +979 -0
  3. package/dist/index.d.ts +19 -28
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +21 -28
  6. package/dist/index.js.map +1 -1
  7. package/dist/react/createTrackingProxy.d.ts +27 -27
  8. package/dist/react/createTrackingProxy.d.ts.map +1 -1
  9. package/dist/react/createTrackingProxy.js +92 -42
  10. package/dist/react/createTrackingProxy.js.map +1 -1
  11. package/dist/react/useForm.d.ts +42 -43
  12. package/dist/react/useForm.d.ts.map +1 -1
  13. package/dist/react/useForm.js +38 -38
  14. package/dist/react/useForm.js.map +1 -1
  15. package/dist/react/usePersist.d.ts +14 -14
  16. package/dist/react/usePersist.js +18 -18
  17. package/dist/react/usePersist.js.map +1 -1
  18. package/dist/react/useStoreContext.d.ts +11 -11
  19. package/dist/react/useStoreContext.js +11 -11
  20. package/dist/react/useTranslator.d.ts +12 -12
  21. package/dist/react/useTranslator.js +12 -12
  22. package/dist/store/applyPatch/applyPatch.d.ts +8 -8
  23. package/dist/store/applyPatch/applyPatch.js +12 -12
  24. package/dist/store/applyPatch/applyPatch.js.map +1 -1
  25. package/dist/store/buildProxy/buildEntityProjectionProxy.js +6 -6
  26. package/dist/store/buildProxy/buildEntityProjectionProxy.js.map +1 -1
  27. package/dist/store/buildProxy/buildListProxy.d.ts +8 -8
  28. package/dist/store/buildProxy/buildListProxy.js +30 -30
  29. package/dist/store/buildProxy/buildListProxy.js.map +1 -1
  30. package/dist/store/buildProxy/buildProxy.d.ts +8 -8
  31. package/dist/store/buildProxy/buildProxy.d.ts.map +1 -1
  32. package/dist/store/buildProxy/buildProxy.js +84 -33
  33. package/dist/store/buildProxy/buildProxy.js.map +1 -1
  34. package/dist/store/buildProxy/computeProxyKeys.d.ts +8 -8
  35. package/dist/store/buildProxy/computeProxyKeys.d.ts.map +1 -1
  36. package/dist/store/buildProxy/computeProxyKeys.js +18 -13
  37. package/dist/store/buildProxy/computeProxyKeys.js.map +1 -1
  38. package/dist/store/buildProxy/handleLazyResolve.d.ts +3 -3
  39. package/dist/store/buildProxy/handleLazyResolve.js +3 -3
  40. package/dist/store/buildProxy/initProxyCaches.d.ts +5 -5
  41. package/dist/store/buildProxy/initProxyCaches.js +5 -5
  42. package/dist/store/compute/computeFieldState.d.ts +3 -3
  43. package/dist/store/compute/computeFieldState.js +8 -8
  44. package/dist/store/compute/computeFieldState.js.map +1 -1
  45. package/dist/store/compute/fieldStateChanged.d.ts +1 -1
  46. package/dist/store/compute/fieldStateChanged.js +1 -1
  47. package/dist/store/compute/recompute/collectGroupComputeNodes.d.ts +4 -4
  48. package/dist/store/compute/recompute/collectGroupComputeNodes.js +7 -7
  49. package/dist/store/compute/recompute/collectGroupComputeNodes.js.map +1 -1
  50. package/dist/store/compute/recompute/recomputeAndNotify.d.ts +3 -3
  51. package/dist/store/compute/recompute/recomputeAndNotify.js +3 -3
  52. package/dist/store/compute/recompute/recomputeLeaves.d.ts +11 -10
  53. package/dist/store/compute/recompute/recomputeLeaves.d.ts.map +1 -1
  54. package/dist/store/compute/recompute/recomputeLeaves.js +26 -27
  55. package/dist/store/compute/recompute/recomputeLeaves.js.map +1 -1
  56. package/dist/store/compute/recompute/recomputeTargeted.d.ts +7 -7
  57. package/dist/store/compute/recompute/recomputeTargeted.js +12 -12
  58. package/dist/store/compute/recompute/recomputeTargeted.js.map +1 -1
  59. package/dist/store/compute/recompute/topologicalSortComputed.d.ts +4 -4
  60. package/dist/store/compute/recompute/topologicalSortComputed.d.ts.map +1 -1
  61. package/dist/store/compute/recompute/topologicalSortComputed.js +11 -13
  62. package/dist/store/compute/recompute/topologicalSortComputed.js.map +1 -1
  63. package/dist/store/compute/recompute/types.d.ts +4 -4
  64. package/dist/store/compute/resolveFlag.d.ts +2 -2
  65. package/dist/store/compute/resolveFlag.js +2 -2
  66. package/dist/store/compute/resolveString.d.ts +5 -5
  67. package/dist/store/compute/resolveString.js +6 -6
  68. package/dist/store/compute/resolveString.js.map +1 -1
  69. package/dist/store/compute/types.d.ts +3 -3
  70. package/dist/store/constants.d.ts +57 -38
  71. package/dist/store/constants.d.ts.map +1 -1
  72. package/dist/store/constants.js +70 -35
  73. package/dist/store/constants.js.map +1 -1
  74. package/dist/store/defineFieldMapping.d.ts +21 -19
  75. package/dist/store/defineFieldMapping.d.ts.map +1 -1
  76. package/dist/store/defineFieldMapping.js +21 -19
  77. package/dist/store/defineFieldMapping.js.map +1 -1
  78. package/dist/store/dirtyTracking/collectInitialSnapshot.js +1 -1
  79. package/dist/store/dirtyTracking/collectInitialSnapshot.js.map +1 -1
  80. package/dist/store/dirtyTracking/recomputeDirtyTargeted.d.ts +3 -3
  81. package/dist/store/dirtyTracking/recomputeDirtyTargeted.js +11 -11
  82. package/dist/store/dirtyTracking/recomputeDirtyTargeted.js.map +1 -1
  83. package/dist/store/dirtyTracking/setGroupRevalidate.d.ts +6 -6
  84. package/dist/store/dirtyTracking/setGroupRevalidate.js +7 -7
  85. package/dist/store/dirtyTracking/setGroupRevalidate.js.map +1 -1
  86. package/dist/store/entityRegistry/entityRegistry.d.ts +72 -72
  87. package/dist/store/entityRegistry/entityRegistry.d.ts.map +1 -1
  88. package/dist/store/entityRegistry/entityRegistry.js +91 -91
  89. package/dist/store/entityRegistry/entityRegistry.js.map +1 -1
  90. package/dist/store/entityRegistry/generateId.d.ts +3 -3
  91. package/dist/store/entityRegistry/generateId.js +3 -3
  92. package/dist/store/entityRegistry/types.d.ts +17 -17
  93. package/dist/store/entityRegistry/types.d.ts.map +1 -1
  94. package/dist/store/flow/buildFlowStepsProxy.d.ts +17 -0
  95. package/dist/store/flow/buildFlowStepsProxy.d.ts.map +1 -0
  96. package/dist/store/flow/buildFlowStepsProxy.js +72 -0
  97. package/dist/store/flow/buildFlowStepsProxy.js.map +1 -0
  98. package/dist/store/flow/defineFlow.d.ts +92 -0
  99. package/dist/store/flow/defineFlow.d.ts.map +1 -0
  100. package/dist/store/flow/defineFlow.js +99 -0
  101. package/dist/store/flow/defineFlow.js.map +1 -0
  102. package/dist/store/flow/flowApi.d.ts +18 -0
  103. package/dist/store/flow/flowApi.d.ts.map +1 -0
  104. package/dist/store/flow/flowApi.js +18 -0
  105. package/dist/store/flow/flowApi.js.map +1 -0
  106. package/dist/store/flow/flowNavigation.d.ts +137 -0
  107. package/dist/store/flow/flowNavigation.d.ts.map +1 -0
  108. package/dist/store/flow/flowNavigation.js +384 -0
  109. package/dist/store/flow/flowNavigation.js.map +1 -0
  110. package/dist/store/flow/flowState.d.ts +41 -0
  111. package/dist/store/flow/flowState.d.ts.map +1 -0
  112. package/dist/store/flow/flowState.js +51 -0
  113. package/dist/store/flow/flowState.js.map +1 -0
  114. package/dist/store/flow/index.d.ts +10 -0
  115. package/dist/store/flow/index.d.ts.map +1 -0
  116. package/dist/store/flow/index.js +6 -0
  117. package/dist/store/flow/index.js.map +1 -0
  118. package/dist/store/groupDeps/createGroupDeps.d.ts +3 -3
  119. package/dist/store/groupDeps/createGroupDeps.js +6 -6
  120. package/dist/store/groupDeps/createGroupDeps.js.map +1 -1
  121. package/dist/store/groupDeps/createTrackingValues.d.ts +9 -9
  122. package/dist/store/groupDeps/createTrackingValues.js +11 -11
  123. package/dist/store/groupDeps/createTrackingValues.js.map +1 -1
  124. package/dist/store/groupDeps/getNodeGroupPath.d.ts +3 -3
  125. package/dist/store/groupDeps/getNodeGroupPath.js +5 -5
  126. package/dist/store/groupDeps/getNodeGroupPath.js.map +1 -1
  127. package/dist/store/groupDeps/getRecipientGroups.d.ts +1 -1
  128. package/dist/store/groupDeps/getRecipientGroups.js +1 -1
  129. package/dist/store/groupDeps/groupDeps.d.ts +7 -7
  130. package/dist/store/groupDeps/groupDeps.js +7 -7
  131. package/dist/store/groupDeps/pairKey.d.ts +3 -3
  132. package/dist/store/groupDeps/pairKey.d.ts.map +1 -1
  133. package/dist/store/groupDeps/pairKey.js +4 -4
  134. package/dist/store/groupDeps/pairKey.js.map +1 -1
  135. package/dist/store/groupDeps/resolveGroupByPath.d.ts +3 -3
  136. package/dist/store/groupDeps/resolveGroupByPath.js +3 -3
  137. package/dist/store/init/createNotificationHub.d.ts +31 -31
  138. package/dist/store/init/createNotificationHub.d.ts.map +1 -1
  139. package/dist/store/init/createNotificationHub.js +36 -37
  140. package/dist/store/init/createNotificationHub.js.map +1 -1
  141. package/dist/store/init/createResolveManager.d.ts +72 -69
  142. package/dist/store/init/createResolveManager.d.ts.map +1 -1
  143. package/dist/store/init/createResolveManager.js +101 -98
  144. package/dist/store/init/createResolveManager.js.map +1 -1
  145. package/dist/store/init/initGroupSubmitting.d.ts +2 -2
  146. package/dist/store/init/initGroupSubmitting.js +4 -4
  147. package/dist/store/init/initGroupSubmitting.js.map +1 -1
  148. package/dist/store/normalizeConfig.d.ts +20 -18
  149. package/dist/store/normalizeConfig.d.ts.map +1 -1
  150. package/dist/store/normalizeConfig.js +31 -29
  151. package/dist/store/normalizeConfig.js.map +1 -1
  152. package/dist/store/onChangePipeline/computeFieldKey.d.ts +2 -2
  153. package/dist/store/onChangePipeline/computeFieldKey.js +2 -2
  154. package/dist/store/onChangePipeline/findOnChangeAncestors.d.ts +2 -2
  155. package/dist/store/onChangePipeline/findOnChangeAncestors.js +4 -4
  156. package/dist/store/onChangePipeline/findOnChangeAncestors.js.map +1 -1
  157. package/dist/store/onChangePipeline/onChangePipeline.d.ts +13 -12
  158. package/dist/store/onChangePipeline/onChangePipeline.d.ts.map +1 -1
  159. package/dist/store/onChangePipeline/onChangePipeline.js +14 -13
  160. package/dist/store/onChangePipeline/onChangePipeline.js.map +1 -1
  161. package/dist/store/persist/drivers.d.ts +7 -7
  162. package/dist/store/persist/drivers.js +8 -8
  163. package/dist/store/persist/drivers.js.map +1 -1
  164. package/dist/store/persist/index.d.ts +1 -1
  165. package/dist/store/persist/persistManager.d.ts +23 -23
  166. package/dist/store/persist/persistManager.d.ts.map +1 -1
  167. package/dist/store/persist/persistManager.js +73 -42
  168. package/dist/store/persist/persistManager.js.map +1 -1
  169. package/dist/store/persist/types.d.ts +23 -23
  170. package/dist/store/persist/types.d.ts.map +1 -1
  171. package/dist/store/persist/types.js +4 -4
  172. package/dist/store/resetPipeline/buildResetPatch.d.ts +5 -5
  173. package/dist/store/resetPipeline/buildResetPatch.js +5 -5
  174. package/dist/store/resetPipeline/collectDefaults.d.ts +5 -5
  175. package/dist/store/resetPipeline/collectDefaults.js +6 -6
  176. package/dist/store/resetPipeline/collectDefaults.js.map +1 -1
  177. package/dist/store/resetPipeline/resetPipeline.d.ts +7 -7
  178. package/dist/store/resetPipeline/resetPipeline.d.ts.map +1 -1
  179. package/dist/store/resetPipeline/resetPipeline.js +17 -12
  180. package/dist/store/resetPipeline/resetPipeline.js.map +1 -1
  181. package/dist/store/resolvePipeline/applyPendingWrites.d.ts +10 -10
  182. package/dist/store/resolvePipeline/applyPendingWrites.d.ts.map +1 -1
  183. package/dist/store/resolvePipeline/applyPendingWrites.js +35 -38
  184. package/dist/store/resolvePipeline/applyPendingWrites.js.map +1 -1
  185. package/dist/store/resolvePipeline/createContextTrackingProxy.d.ts +8 -7
  186. package/dist/store/resolvePipeline/createContextTrackingProxy.d.ts.map +1 -1
  187. package/dist/store/resolvePipeline/createContextTrackingProxy.js +6 -5
  188. package/dist/store/resolvePipeline/createContextTrackingProxy.js.map +1 -1
  189. package/dist/store/resolvePipeline/createValuesTrackingProxy.d.ts +43 -43
  190. package/dist/store/resolvePipeline/createValuesTrackingProxy.d.ts.map +1 -1
  191. package/dist/store/resolvePipeline/createValuesTrackingProxy.js +70 -70
  192. package/dist/store/resolvePipeline/createValuesTrackingProxy.js.map +1 -1
  193. package/dist/store/resolvePipeline/executeListResolve.d.ts +14 -14
  194. package/dist/store/resolvePipeline/executeListResolve.js +27 -27
  195. package/dist/store/resolvePipeline/executeListResolve.js.map +1 -1
  196. package/dist/store/resolvePipeline/executeResolve.d.ts +15 -15
  197. package/dist/store/resolvePipeline/executeResolve.js +46 -46
  198. package/dist/store/resolvePipeline/executeResolve.js.map +1 -1
  199. package/dist/store/store/NodeRegistry/nodeRegistry.d.ts +69 -56
  200. package/dist/store/store/NodeRegistry/nodeRegistry.d.ts.map +1 -1
  201. package/dist/store/store/NodeRegistry/nodeRegistry.js +94 -78
  202. package/dist/store/store/NodeRegistry/nodeRegistry.js.map +1 -1
  203. package/dist/store/store/NodeRegistry/nodeUtils.d.ts +5 -5
  204. package/dist/store/store/NodeRegistry/nodeUtils.d.ts.map +1 -1
  205. package/dist/store/store/NodeRegistry/nodeUtils.js +5 -5
  206. package/dist/store/store/NodeRegistry/nodeUtils.js.map +1 -1
  207. package/dist/store/store/groupDepsMap.d.ts +23 -23
  208. package/dist/store/store/groupDepsMap.d.ts.map +1 -1
  209. package/dist/store/store/groupDepsMap.js +40 -34
  210. package/dist/store/store/groupDepsMap.js.map +1 -1
  211. package/dist/store/store/hasComputedProps.d.ts +2 -2
  212. package/dist/store/store/hasComputedProps.js +2 -2
  213. package/dist/store/store/nodeMap.d.ts +5 -5
  214. package/dist/store/store/nodeMap.js +7 -7
  215. package/dist/store/store/nodeMap.js.map +1 -1
  216. package/dist/store/store/palistor.d.ts +80 -80
  217. package/dist/store/store/palistor.d.ts.map +1 -1
  218. package/dist/store/store/palistor.js +151 -165
  219. package/dist/store/store/palistor.js.map +1 -1
  220. package/dist/store/store/registerNodes.d.ts +10 -10
  221. package/dist/store/store/registerNodes.d.ts.map +1 -1
  222. package/dist/store/store/registerNodes.js +33 -18
  223. package/dist/store/store/registerNodes.js.map +1 -1
  224. package/dist/store/store/serviceRegistry.d.ts +8 -8
  225. package/dist/store/store/serviceRegistry.d.ts.map +1 -1
  226. package/dist/store/store/serviceRegistry.js +8 -8
  227. package/dist/store/store/serviceRegistry.js.map +1 -1
  228. package/dist/store/store/types.d.ts +277 -223
  229. package/dist/store/store/types.d.ts.map +1 -1
  230. package/dist/store/submitPipeline/applyLeafBeforeSubmit.d.ts +2 -2
  231. package/dist/store/submitPipeline/applyLeafBeforeSubmit.js +2 -2
  232. package/dist/store/submitPipeline/collectLeafStates.d.ts +2 -2
  233. package/dist/store/submitPipeline/collectLeafStates.js +2 -2
  234. package/dist/store/submitPipeline/submitPipeline.d.ts +8 -8
  235. package/dist/store/submitPipeline/submitPipeline.d.ts.map +1 -1
  236. package/dist/store/submitPipeline/submitPipeline.js +15 -11
  237. package/dist/store/submitPipeline/submitPipeline.js.map +1 -1
  238. package/dist/store/submitPipeline/types.d.ts +1 -1
  239. package/dist/store/submitPipeline/types.d.ts.map +1 -1
  240. package/dist/store/traversal/nodeClassifier.d.ts +9 -9
  241. package/dist/store/traversal/nodeClassifier.d.ts.map +1 -1
  242. package/dist/store/traversal/nodeClassifier.js +11 -11
  243. package/dist/store/traversal/nodeClassifier.js.map +1 -1
  244. package/dist/store/traversal/walkFull.d.ts +14 -14
  245. package/dist/store/traversal/walkFull.js +2 -2
  246. package/dist/store/valuesCache/valuesCache.d.ts +9 -9
  247. package/dist/store/valuesCache/valuesCache.d.ts.map +1 -1
  248. package/dist/store/valuesCache/valuesCache.js +6 -6
  249. package/dist/store/writePipeline/formatPatch.d.ts +5 -5
  250. package/dist/store/writePipeline/formatPatch.js +7 -7
  251. package/dist/store/writePipeline/formatPatch.js.map +1 -1
  252. package/dist/store/writePipeline/formatValue.d.ts +5 -5
  253. package/dist/store/writePipeline/formatValue.js +5 -5
  254. package/dist/store/writePipeline/mergeChanged.d.ts +4 -4
  255. package/dist/store/writePipeline/mergeChanged.js +4 -4
  256. package/dist/store/writePipeline/runSetter.d.ts +6 -6
  257. package/dist/store/writePipeline/runSetter.js +8 -8
  258. package/dist/store/writePipeline/storeValue.d.ts +3 -3
  259. package/dist/store/writePipeline/storeValue.js +3 -3
  260. package/dist/store/writePipeline/types.d.ts +4 -4
  261. package/dist/store/writePipeline/types.d.ts.map +1 -1
  262. package/dist/store/writePipeline/writePipeline.d.ts +7 -7
  263. package/dist/store/writePipeline/writePipeline.d.ts.map +1 -1
  264. package/dist/store/writePipeline/writePipeline.js +15 -15
  265. package/dist/store/writePipeline/writePipeline.js.map +1 -1
  266. package/package.json +11 -4
  267. package/dist/store/compute/recompute/collectGroupLeafNodes.d.ts +0 -11
  268. package/dist/store/compute/recompute/collectGroupLeafNodes.d.ts.map +0 -1
  269. package/dist/store/compute/recompute/collectGroupLeafNodes.js +0 -26
  270. package/dist/store/compute/recompute/collectGroupLeafNodes.js.map +0 -1
  271. package/dist/store/fieldMapping.typecheck.d.ts +0 -2
  272. package/dist/store/fieldMapping.typecheck.d.ts.map +0 -1
  273. package/dist/store/fieldMapping.typecheck.js +0 -71
  274. package/dist/store/fieldMapping.typecheck.js.map +0 -1
  275. package/dist/store/submitPipeline/getSubValues.d.ts +0 -9
  276. package/dist/store/submitPipeline/getSubValues.d.ts.map +0 -1
  277. package/dist/store/submitPipeline/getSubValues.js +0 -26
  278. package/dist/store/submitPipeline/getSubValues.js.map +0 -1
@@ -1,61 +1,62 @@
1
1
  import type { PersistManager } from "../persist/persistManager";
2
2
  import type { EntityNode } from "../entityRegistry/types";
3
3
  import type { MappableKey, MappableConfigKey } from "../constants";
4
+ import type { AnyFlowStep, FlowError, FlowStep, FlowValues, InferFlowSteps, StepStatus } from "../flow/defineFlow";
4
5
  /**
5
- * Внутренний тип для рекурсивного обхода дерева конфига.
6
- * Используется в registerNodes, buildProxy, applyPatch, recomputeAll и др.
6
+ * Internal type for recursively walking the config tree.
7
+ * Used by registerNodes, buildProxy, applyPatch, recomputeAll, etc.
7
8
  */
8
9
  export interface AnyConfigNode {
9
10
  [key: string]: AnyConfigNode | unknown;
10
11
  }
11
12
  /**
12
- * Функция перевода (next-intl, i18next, …).
13
- * label/placeholder/description в конфиге могут быть функцией от TranslateFn.
14
- * Принимает любое количество аргументовсовместима с next-intl `t`, i18next `t` и др.
13
+ * Translation function (next-intl, i18next, …).
14
+ * label/placeholder/description in the config may be functions of TranslateFn.
15
+ * Accepts any number of arguments compatible with next-intl `t`, i18next `t`, etc.
15
16
  */
16
17
  export type TranslateFn = (...args: any[]) => string;
17
18
  /**
18
- * Тип конфигурации формы: объект, где каждый ключ узел конфига с типами TValues.
19
+ * Form config type: an object where every key is a config node typed over TValues.
19
20
  */
20
21
  export type FormConfig<TValues = Record<string, unknown>> = Record<string, ConfigNode<any, TValues>>;
21
22
  import type { NotifyFn, Resolve } from "../resolvePipeline";
22
23
  import type { SubmitResult } from "../submitPipeline/submitPipeline";
23
- /** Функция отписки от подписки. */
24
+ /** Unsubscribe function returned by subscriptions. */
24
25
  export type Unsubscribe = () => void;
25
26
  /**
26
- * Значение либо функция, вычисляемая из текущих значений формы.
27
- * Большинство свойств конфига (isVisible, isRequired, label, …) могут быть
28
- * либо статическим значением, либо функцией от всего дерева значений.
27
+ * A value, or a function computing it from the current form values.
28
+ * Most config properties (isVisible, isRequired, label, …) can be either a
29
+ * static value or a function of the whole values tree.
29
30
  *
30
31
  * @example
31
- * // статическое
32
+ * // static
32
33
  * isVisible: true
33
- * // вычисляемое
34
+ * // computed
34
35
  * isVisible: (values) => values.paymentType === "bank"
35
36
  */
36
37
  export type MaybeComputed<TResult, TValues = Record<string, unknown>> = TResult | ((values: TValues) => TResult);
37
38
  /**
38
- * Используется для label / placeholder / description, которые могут быть:
39
- * - статической строкой
40
- * - `(t: TranslateFn, values: TValues) => string` — перевод + вычисление
39
+ * Used for label / placeholder / description, which can be:
40
+ * - a static string
41
+ * - `(t: TranslateFn, values: TValues) => string` — translation + computation
41
42
  */
42
43
  export type MaybeTranslatable<TResult, TValues = Record<string, unknown>> = TResult | ((t: TranslateFn, values: TValues) => TResult);
43
44
  /**
44
- * Глубокая опциональная версия значений.
45
- * Рекурсирует только в «плоские» объекты; массивы, Date, Map, Set и т.д.
46
- * остаются как есть.
45
+ * Deeply optional version of the values.
46
+ * Recurses only into "plain" objects; arrays, Date, Map, Set, etc.
47
+ * are left as-is.
47
48
  */
48
49
  export type DeepPartialValues<T> = {
49
50
  [K in keyof T]?: T[K] extends readonly unknown[] ? T[K] : T[K] extends Date ? T[K] : T[K] extends Map<unknown, unknown> ? T[K] : T[K] extends Set<unknown> ? T[K] : T[K] extends Record<string, unknown> ? DeepPartialValues<T[K]> : T[K];
50
51
  };
51
52
  /**
52
- * Расширяет тип значения, чтобы допустить типичные «входные» типы форматтеров.
53
- * Числовые поля принимают string (Input возвращает строку), булевы — string/number.
54
- * Остальные типы остаются как есть.
53
+ * Widens a value type to accept typical formatter "input" types.
54
+ * Number fields accept string (an Input yields strings), booleans accept
55
+ * string/number. Other types are left as-is.
55
56
  */
56
57
  type ProxyValueType<T> = T extends number ? T | string : T extends boolean ? T | string | number : T;
57
58
  /**
58
- * Метаданные типа поля (для будущей валидации по типам / кодогенерации).
59
+ * Field type metadata (for future type-based validation / codegen).
59
60
  */
60
61
  export interface FieldTypeMeta {
61
62
  readonly dataType: "String" | "Number" | "Boolean" | "Date" | "Array" | "Object";
@@ -63,17 +64,17 @@ export interface FieldTypeMeta {
63
64
  }
64
65
  export type { Setter } from "../writePipeline/writePipeline";
65
66
  /**
66
- * Универсальный узел конфигаописывает и поле, и группу.
67
+ * Universal config nodedescribes both a field and a group.
67
68
  *
68
- * Поведение узла определяется наличием свойств:
69
- * - Есть `value` → листовой узел (поле формы)
70
- * - Нет `value` → групповой узел (контейнер для дочерних)
69
+ * The node's behavior is determined by which properties are present:
70
+ * - Has `value` → leaf node (form field)
71
+ * - No `value` → group node (container for children)
71
72
  *
72
- * Все свойства кроме `value` опциональны.
73
- * Любое computed-свойство может быть константой или функцией от `TValues`.
73
+ * All properties except `value` are optional.
74
+ * Any computed property can be a constant or a function of `TValues`.
74
75
  *
75
- * @template TValue — тип значения поля (актуально для листовых узлов)
76
- * @template TValues — форма дерева всех значений (по умолчанию Record<string,any>)
76
+ * @template TValue — the field's value type (relevant for leaf nodes)
77
+ * @template TValues — shape of the whole values tree (defaults to Record<string,any>)
77
78
  */
78
79
  export interface ConfigNode<TValue = unknown, TValues = Record<string, unknown>> {
79
80
  value?: MaybeComputed<TValue, TValues>;
@@ -81,41 +82,41 @@ export interface ConfigNode<TValue = unknown, TValues = Record<string, unknown>>
81
82
  placeholder?: MaybeTranslatable<string, TValues>;
82
83
  description?: MaybeTranslatable<string, TValues>;
83
84
  /**
84
- * Возвращает строку с ошибкой или falsy-значение если поле валидно.
85
- * `false` допускается для удобства паттерна `!v && "required"`.
85
+ * Returns an error string, or a falsy value when the field is valid.
86
+ * `false` is allowed for the convenience of the `!v && "required"` pattern.
86
87
  */
87
88
  validate?: (value: TValue, values: TValues, t: TranslateFn) => string | undefined | false;
88
- /** Преобразует входное значение перед сохранением (например, обрезает пробелы) */
89
+ /** Transforms the input value before storing it (e.g. trims whitespace). */
89
90
  formatter?: (value: string | boolean, values: TValues) => string | number | boolean;
90
- /** Сайд-эффект записи: возвращает патч других полей */
91
+ /** Write side-effect: returns a patch for other fields. */
91
92
  setter?: (value: TValue, values: TValues, previousValue: TValue | undefined) => DeepPartialValues<TValues>;
92
- /** Дополнительные пропсы для UI-компонента */
93
+ /** Extra props for the UI component. */
93
94
  componentProps?: Readonly<Record<string, unknown>>;
94
- /** Список имён полей, при изменении которых пересчитывается состояние этого поля */
95
+ /** Field names whose changes trigger a recompute of this field's state. */
95
96
  dependencies?: readonly string[];
96
- /** Метаданные типа поля */
97
+ /** Field type metadata. */
97
98
  types?: FieldTypeMeta;
98
99
  isRequired?: MaybeComputed<boolean, TValues>;
99
100
  isReadOnly?: MaybeComputed<boolean, TValues>;
100
101
  isDisabled?: MaybeComputed<boolean, TValues>;
101
102
  isVisible?: MaybeComputed<boolean, TValues>;
102
103
  /**
103
- * Трансформирует значение перед submit (не мутирует store).
104
- * На листовом узле: `(value, values) → value`
105
- * На групповом узле: `(values) → values`
104
+ * Transforms the value before submit (does not mutate the store).
105
+ * On a leaf node: `(value, values) → value`
106
+ * On a group node: `(values) → values`
106
107
  */
107
108
  beforeSubmit?: ((value: TValue, values: TValues) => TValue) | ((values: TValues) => TValues);
108
- /** Callback отправки формы. Вызывается после валидации в submit pipeline. */
109
+ /** Form submit callback. Invoked after validation in the submit pipeline. */
109
110
  onSubmit?: (value: TValue | TValues, store: ProxyStore<any>, parent?: any) => Promise<unknown> | unknown;
110
- /** Пост-обработка после успешного onSubmit. */
111
+ /** Post-processing after a successful onSubmit. */
111
112
  afterSubmit?: (result: unknown, actions: {
112
113
  reset: () => void;
113
114
  }) => void | Promise<void>;
114
- /** Трансформер для reset: принимает defaults, возвращает окончательные значения. */
115
+ /** Reset transformer: receives defaults, returns the final values. */
115
116
  reset?: (defaults: TValues) => TValues;
116
117
  /**
117
- * Вызывается после изменения любого поля в группе (fire-and-forget).
118
- * Может вернуть патч для мержа обратно в store.
118
+ * Called after any field in the group changes (fire-and-forget).
119
+ * May return a patch to merge back into the store.
119
120
  */
120
121
  onChange?: (info: {
121
122
  fieldKey: string;
@@ -132,16 +133,15 @@ export interface ConfigNode<TValue = unknown, TValues = Record<string, unknown>>
132
133
  resolve?: Resolve<TValue>;
133
134
  }
134
135
  /**
135
- * Ключи конфига, которые не являются дочерними полями (скрываются при маппинге
136
- * группового узла).
136
+ * Config keys that are not child fields (hidden when mapping over a group node).
137
137
  */
138
138
  type ConfigSkipKeys = "value" | "label" | "placeholder" | "description" | "validate" | "formatter" | "setter" | "isRequired" | "isReadOnly" | "isDisabled" | "isVisible" | "isInvalid" | "errorMessage" | "componentProps" | "types" | "dependencies" | "onSubmit" | "beforeSubmit" | "afterSubmit" | "reset" | "onChange" | "resolve" | "deps";
139
139
  /**
140
- * Форма доступного через прокси листового поля.
141
- * Все функции (isVisible, validate, …) уже вычислены.
140
+ * Shape of a leaf field as seen through the proxy.
141
+ * All functions (isVisible, validate, …) are already evaluated.
142
142
  */
143
143
  export interface FieldProxyNode<TValue = unknown> {
144
- /** Чтение возвращает типизированное значение, запись принимает расширенный тип (string для number-полей и т.д.) */
144
+ /** Reads return the typed value; writes accept a widened type (string for number fields, etc.). */
145
145
  get value(): TValue;
146
146
  set value(v: ProxyValueType<TValue>);
147
147
  readonly label: string | undefined;
@@ -151,26 +151,26 @@ export interface FieldProxyNode<TValue = unknown> {
151
151
  readonly isReadOnly: boolean;
152
152
  readonly isDisabled: boolean;
153
153
  readonly isVisible: boolean;
154
- /** true если поле имеет ошибку валидации */
154
+ /** true when the field has a validation error. */
155
155
  readonly isInvalid: boolean | undefined;
156
156
  readonly errorMessage: string | undefined;
157
- /** true если текущее значение отличается от initial */
157
+ /** true when the current value differs from the initial one. */
158
158
  readonly dirty: boolean;
159
159
  readonly onValueChange: (v: ProxyValueType<TValue>) => void;
160
- /** true пока выполняется submit pipeline (аналогично GroupProxyNode). */
160
+ /** true while the submit pipeline is running (same as GroupProxyNode). */
161
161
  readonly submitting: boolean;
162
162
  /** Submit pipeline: submitting → beforeSubmit → validate → onSubmit → afterSubmit. */
163
163
  submit(): Promise<SubmitResult>;
164
164
  }
165
- /** Извлекает тип значения из узла конфига. */
165
+ /** Extracts the value type from a config node. */
166
166
  type ExtractNodeValue<T> = T extends {
167
167
  value: (...args: any[]) => infer R;
168
168
  } ? R : T extends {
169
169
  value: infer V;
170
170
  } ? V : never;
171
171
  /**
172
- * Вычисленные флаги группового узла (присутствуют, если заданы в конфиге;
173
- * могут быть boolean-константой или функциейв прокси уже разрешены).
172
+ * Computed flags of a group node (present when set in the config;
173
+ * may be a boolean constant or a function already resolved in the proxy).
174
174
  */
175
175
  export interface GroupProxyNode {
176
176
  readonly isVisible: boolean;
@@ -179,34 +179,34 @@ export interface GroupProxyNode {
179
179
  readonly isDisabled: boolean | undefined;
180
180
  readonly isInvalid: boolean | undefined;
181
181
  readonly errorMessage: string | undefined;
182
- /** true пока выполняется submit pipeline. */
182
+ /** true while the submit pipeline is running. */
183
183
  readonly submitting: boolean;
184
184
  /** true while async resolver is loading (only for nodes with resolve). */
185
185
  readonly loading: boolean;
186
- /** true если хотя бы одно поле в группе отличается от initial. */
186
+ /** true when at least one field in the group differs from its initial value. */
187
187
  readonly dirty: boolean;
188
188
  /**
189
- * true после первого неудачного submit — ошибки показываются в реальном времени.
190
- * false до первого submit — ошибки скрыты.
189
+ * true after the first failed submit — errors are shown in real time.
190
+ * false before the first submit — errors are hidden.
191
191
  */
192
192
  readonly revalidate: boolean;
193
- /** Текущие значения всех листовых полей поддерева в виде вложенного объекта. Живая ссылка (не клон). */
193
+ /** Current values of all leaf fields in the subtree as a nested object. Live reference (not a clone). */
194
194
  readonly values: Record<string, unknown>;
195
195
  /** Submit pipeline: submitting → beforeSubmit → validate → onSubmit → afterSubmit. */
196
196
  submit(): Promise<SubmitResult>;
197
- /** Reset поддерево к defaults из конфига (или к переданным значениям). */
197
+ /** Resets the subtree to config defaults (or to the provided values). */
198
198
  reset(values?: Record<string, unknown>): void;
199
199
  /**
200
- * Bulk-обновление значений: применяет патч к поддереву за один recompute + notify.
201
- * Без setters (чтобы избежать рекурсии) и без форматтеров.
202
- * Используется для подлива серверных данных или bulk-изменений из React.
200
+ * Bulk value update: applies a patch to the subtree in a single recompute + notify.
201
+ * Skips setters (to avoid recursion) and formatters.
202
+ * Used for feeding in server data or bulk changes from React.
203
203
  */
204
204
  setValues(patch: Record<string, unknown>): void;
205
205
  }
206
206
  /**
207
- * Конфигурация resolver-а для ListNode (аналог Resolve для группы, но возвращает
208
- * массив entity-данных). Минимальный интерфейс без импорта Resolve из resolvePipeline
209
- * (избегает циклических зависимостей).
207
+ * Resolver configuration for a ListNode (like Resolve for a group, but returns
208
+ * an array of entity records). Minimal interface that avoids importing Resolve
209
+ * from resolvePipeline (prevents circular dependencies).
210
210
  */
211
211
  export interface ListResolveConfig {
212
212
  /** Async data loader — returns array of entity records. */
@@ -228,45 +228,45 @@ export interface ListResolveConfig {
228
228
  };
229
229
  }
230
230
  /**
231
- * Конфигурация уровня списка (второй элемент ListNode-массива).
232
- * Resolver и прочие опции уровня списка добавляются здесь.
231
+ * List-level configuration (second element of a ListNode array).
232
+ * The resolver and other list-level options go here.
233
233
  */
234
234
  export interface ListConfig {
235
235
  resolve?: ListResolveConfig;
236
236
  }
237
237
  /**
238
- * Внутреннее состояние спискаЕДИНЫЙ кубик «список» (root + per-entity).
238
+ * Internal list statethe SINGLE "list" building block (root + per-entity).
239
239
  *
240
- * Идентичность узла для tracking/resolve сам объект `ListState` (ключ в хабе),
241
- * а не отдельное поле version. Root-list вырожденный случай `ownerEntity === null`;
242
- * per-entity-list (вариант C) `ownerEntity` указывает на владельца.
240
+ * Node identity for tracking/resolve is the `ListState` object itself (hub
241
+ * key), not a separate version field. A root list is the degenerate case
242
+ * `ownerEntity === null`; a per-entity list points to its owner.
243
243
  *
244
- * Root-`ListState` хранится в `NodeRegistry.listStates` (ключ `listConfigNode`),
245
- * per-entity в `owner.lists` (ключ — тот же `listConfigNode`).
244
+ * Root `ListState` lives in `NodeRegistry.listStates` (keyed by `listConfigNode`),
245
+ * per-entity ones live in `owner.lists` (same `listConfigNode` key).
246
246
  */
247
247
  export interface ListState {
248
- /** Сам array-узел конфига [template, listConfig?] — ключ во всех реестрах. */
248
+ /** The array config node [template, listConfig?] — key in all registries. */
249
249
  listConfigNode: object;
250
- /** Шаблон элемента — describes поля для отображения. listConfigNode[0]. */
250
+ /** Item template — describes the fields to render. listConfigNode[0]. */
251
251
  template: object;
252
- /** Конфигурация списка (resolve и т.д.). listConfigNode[1] — опционально. */
252
+ /** List configuration (resolve etc.). listConfigNode[1] — optional. */
253
253
  listConfig?: ListConfig;
254
- /** Владелец списка. `null` = root list; иначе entity-владелец (вариант C). */
254
+ /** List owner. `null` = root list; otherwise the owning entity. */
255
255
  ownerEntity: EntityNode | null;
256
- /** ID сущностей, входящих в список (в порядке отображения). */
256
+ /** IDs of the entities in the list (in display order). */
257
257
  itemIds: string[];
258
- /** Сохраняется при init/resolve — для dirty-tracking по составу. */
258
+ /** Captured at init/resolve — used for membership dirty-tracking. */
259
259
  initialItemIds: string[];
260
260
  }
261
261
  /**
262
- * Прокси-интерфейс для списка (ListNode в конфиге).
263
- * TItem — тип одного элемента (EntityProjectionProxy в Phase 2B).
262
+ * Proxy interface for a list (ListNode in the config).
263
+ * TItem — type of a single item (EntityProjectionProxy).
264
264
  */
265
265
  export interface ListProxyNode<TItem> {
266
266
  readonly items: ReadonlyArray<TItem>;
267
267
  readonly length: number;
268
268
  readonly loading: boolean;
269
- /** true если состав списка изменился с момента init/последнего resolve. */
269
+ /** true when list membership changed since init/last resolve. */
270
270
  readonly dirty: boolean;
271
271
  add(id: string): void;
272
272
  add(values: Record<string, unknown>): TItem;
@@ -279,76 +279,126 @@ export interface ListProxyNode<TItem> {
279
279
  }
280
280
  declare const __palistorRefBrand: unique symbol;
281
281
  declare const __typedListBrand: unique symbol;
282
- /** Opaque-ссылка на entity proxy. Передаётся как prop, разворачивается через useForm(). */
282
+ /** Opaque reference to an entity proxy. Passed as a prop, unwrapped via useForm(). */
283
283
  export type PalistorRef<T extends Record<string, any>> = {
284
284
  readonly [__palistorRefBrand]: T;
285
285
  } & object;
286
- /** Типизированный список entity. */
286
+ /** Typed entity list. */
287
287
  export type PalistorList<T extends Record<string, any>> = ListProxyNode<PalistorRef<T>>;
288
- /** Маркерный тип для typed list node в конфиге. */
288
+ /** Marker type for a typed list node in the config. */
289
289
  export type TypedListNode<TEntity extends Record<string, any>> = readonly [any, any?] & {
290
290
  readonly [__typedListBrand]: TEntity;
291
291
  };
292
- /** Typed resolver для списка. */
292
+ /** Typed list resolver. */
293
293
  export type ListResolver<TEntity extends Record<string, any>> = (values: any, store: ProxyStore<any>) => Promise<TEntity[]>;
294
- /** Typed template: каждый ключ Entity → ConfigNode с нужным типом value. */
294
+ /** Typed template: each Entity key → ConfigNode with the matching value type. */
295
295
  export type TemplateConfig<TEntity extends Record<string, any>> = {
296
296
  [K in keyof TEntity]: ConfigNode<TEntity[K], TEntity>;
297
297
  };
298
- /** Извлечь entity type из PalistorRef. */
298
+ /** Extract the entity type from a PalistorRef. */
299
299
  export type InferEntity<T> = T extends PalistorRef<infer E> ? E : never;
300
300
  /**
301
- * Рекурсивно конвертирует узел конфига в его прокси-тип:
301
+ * Proxy of a single flow step: the step config's regular group proxy,
302
+ * enriched with the computed `status` (see {@link StepStatus}).
303
+ */
304
+ export type FlowStepProxy<C, M extends FieldMapping = {}> = ConfigNodeToProxy<C, M> & {
305
+ readonly status: StepStatus;
306
+ };
307
+ /**
308
+ * Proxy of the step collection (flow.steps): access by index (tuple), by key,
309
+ * plus a live `.current` reference to the active step's proxy.
310
+ */
311
+ export type FlowStepsProxy<S extends readonly AnyFlowStep[], M extends FieldMapping = {}> = {
312
+ readonly [I in keyof S]: S[I] extends FlowStep<any, infer C> ? FlowStepProxy<C, M> : never;
313
+ } & {
314
+ readonly [Step in S[number] as Step["key"]]: FlowStepProxy<Step["config"], M>;
315
+ } & {
316
+ /** Proxy of the active step — replaced on every navigation. */
317
+ readonly current: FlowStepProxy<S[number]["config"], M>;
318
+ };
319
+ /**
320
+ * Proxy of a flow node (defineFlow): group proxy + navigation state and methods.
321
+ */
322
+ export type FlowProxyNode<S extends readonly AnyFlowStep[], M extends FieldMapping = {}> = Omit<ApplyFieldMapping<GroupProxyNode, M>, "values"> & {
323
+ /** Key of the active step (reactive). */
324
+ readonly currentStepKey: S[number]["key"];
325
+ /** Index of the active step (reactive). */
326
+ readonly currentStepIndex: number;
327
+ /** true when the visit stack is non-empty (reliable guard for a Back button). */
328
+ readonly canGoBack: boolean;
329
+ /** Visit path: [...visitStack, currentStepKey] (reactive). */
330
+ readonly history: readonly string[];
331
+ /** Errors from the last validate()/finalization (reactive). */
332
+ readonly errors: ReadonlyArray<FlowError>;
333
+ /** Step collection: steps[0], steps.key, steps.current, steps.length. */
334
+ readonly steps: FlowStepsProxy<S, M>;
335
+ /** Accumulated values of all steps — live reference (like a group's). */
336
+ readonly values: FlowValues<S>;
337
+ /** Advance to the next VISIBLE step; if none remain — finalize via submit(). */
338
+ nextStep(): void;
339
+ /** Go back along the visit stack. No-op when the stack is empty. */
340
+ back(): void;
341
+ /** Jump to a step by key or index. Throws on an unknown key/index. */
342
+ goTo(keyOrIndex: S[number]["key"] | number): void;
343
+ /** Validate visited steps → errors land in flow.errors. Empty array = valid. */
344
+ validate(): FlowError[];
345
+ };
346
+ /**
347
+ * Recursively converts a config node into its proxy type:
348
+ * - FlowNode (defineFlow) → `FlowProxyNode<S>`
302
349
  * - TypedListNode (defineList<TEntity>) → `ListProxyNode<PalistorRef<TEntity>>`
303
- * - ListNode (массив `[template, listConfig?]`) → `ListProxyNode<...>`
304
- * - Листовой узел (есть `value`) → `FieldProxyNode<TValue>`
305
- * - Групповой узел → `GroupProxyNode & { дочерние поля… }`
350
+ * - ListNode (array `[template, listConfig?]`) → `ListProxyNode<...>`
351
+ * - Leaf node (has `value`) → `FieldProxyNode<TValue>`
352
+ * - Group node → `GroupProxyNode & { child fields… }`
306
353
  */
307
- type ConfigNodeToProxy<T, M extends FieldMapping = {}> = T extends {
354
+ type ConfigNodeToProxy<T, M extends FieldMapping = {}> = [
355
+ InferFlowSteps<T>
356
+ ] extends [never] ? T extends {
308
357
  readonly [__typedListBrand]: infer TEntity extends Record<string, any>;
309
358
  } ? ApplyFieldMapping<ListProxyNode<PalistorRef<TEntity>>, M> : T extends readonly [infer Item, ...any[]] ? ApplyFieldMapping<ListProxyNode<ConfigNodeToProxy<Item, M>>, M> : T extends {
310
359
  value: any;
311
360
  } ? ApplyFieldMapping<FieldProxyNode<ExtractNodeValue<T>>, M> : T extends Record<string, any> ? ApplyFieldMapping<GroupProxyNode, M> & {
312
361
  [K in keyof T as K extends ConfigSkipKeys ? never : K]: ConfigNodeToProxy<T[K], M>;
313
- } : never;
362
+ } : never : FlowProxyNode<InferFlowSteps<T>, M>;
314
363
  /**
315
- * Полный прокси для конфига формы: каждый ключ маппируется в прокси-узел.
316
- * Корневой прокси также включает GroupProxyNode (submit, reset, setValues, dirty, …).
364
+ * Full proxy for a form config: every key maps to a proxy node.
365
+ * The root proxy also includes GroupProxyNode (submit, reset, setValues, dirty, …).
317
366
  *
318
- * `M` карта переименования полей (см. {@link FieldMapping}). По умолчанию `{}`
319
- * (identity: имена свойств не меняются).
367
+ * `M` is the field rename map (see {@link FieldMapping}). Defaults to `{}`
368
+ * (identity: property names are unchanged).
320
369
  */
321
370
  export type ConfigProxy<TConfig extends Record<string, any>, M extends FieldMapping = {}> = ApplyFieldMapping<GroupProxyNode, M> & {
322
371
  [K in keyof TConfig]: ConfigNodeToProxy<TConfig[K], M>;
323
372
  };
324
373
  declare const __rawStoreBrand: unique symbol;
325
374
  /**
326
- * Маркер «сырого» узла из `store.proxy`. Не передавайте такие значения в
327
- * `useForm()` — используйте `useForm(store)` и обращайтесь к поддеревьям
328
- * через возвращённый tracking-proxy.
375
+ * Marker of a "raw" node from `store.proxy`. Do not pass such values to
376
+ * `useForm()` — call `useForm(store)` and access subtrees through the
377
+ * returned tracking proxy.
329
378
  */
330
379
  export interface RawStoreProxyMarker {
331
380
  readonly [__rawStoreBrand]: "Do not pass store.proxy or store.proxy.subtree to useForm. Use: const form = useForm(store); then form.subtree";
332
381
  }
333
382
  /**
334
- * Та же рекурсивная конвертация конфига в прокси, что и `ConfigNodeToProxy`,
335
- * но на каждом уровне (группа / лист / список) пересекается с
336
- * `RawStoreProxyMarker`, чтобы бренд распространялся по всему дереву.
383
+ * Same recursive config→proxy conversion as `ConfigNodeToProxy`, but every
384
+ * level (group / leaf / list) is intersected with `RawStoreProxyMarker` so
385
+ * the brand propagates through the whole tree.
337
386
  */
338
- type ConfigNodeToProxyRaw<T, M extends FieldMapping = {}> = T extends {
387
+ type ConfigNodeToProxyRaw<T, M extends FieldMapping = {}> = [
388
+ InferFlowSteps<T>
389
+ ] extends [never] ? T extends {
339
390
  readonly [__typedListBrand]: infer TEntity extends Record<string, any>;
340
391
  } ? ApplyFieldMapping<ListProxyNode<PalistorRef<TEntity>>, M> & RawStoreProxyMarker : T extends readonly [infer Item, ...any[]] ? ApplyFieldMapping<ListProxyNode<ConfigNodeToProxyRaw<Item, M>>, M> & RawStoreProxyMarker : T extends {
341
392
  value: any;
342
393
  } ? ApplyFieldMapping<FieldProxyNode<ExtractNodeValue<T>>, M> & RawStoreProxyMarker : T extends Record<string, any> ? ApplyFieldMapping<GroupProxyNode, M> & RawStoreProxyMarker & {
343
394
  [K in keyof T as K extends ConfigSkipKeys ? never : K]: ConfigNodeToProxyRaw<T[K], M>;
344
- } : never;
395
+ } : never : FlowProxyNode<InferFlowSteps<T>, M> & RawStoreProxyMarker;
345
396
  /**
346
- * Тип значения `store.proxy`. Структурно повторяет `ConfigProxy<TConfig>`,
347
- * но на каждом узле дерева добавляет {@link RawStoreProxyMarker} —
348
- * это позволяет TypeScript ругаться на `useForm(store.proxy.X)`.
397
+ * Type of `store.proxy`. Structurally identical to `ConfigProxy<TConfig>`,
398
+ * but every node of the tree carries {@link RawStoreProxyMarker} — which
399
+ * lets TypeScript reject `useForm(store.proxy.X)`.
349
400
  *
350
- * Передача такого значения (или его поддерева) в `useForm` ведёт к
351
- * ошибке вида:
401
+ * Passing such a value (or its subtree) into `useForm` produces an error like:
352
402
  * Argument of type 'X' is not assignable to parameter of type
353
403
  * '_PALISTOR_ERROR__do_not_pass_store_proxy_subtree_to_useForm__call_useForm_store_first'.
354
404
  */
@@ -356,8 +406,8 @@ export type RawStoreProxy<TConfig extends Record<string, any>, M extends FieldMa
356
406
  [K in keyof TConfig]: ConfigNodeToProxyRaw<TConfig[K], M>;
357
407
  };
358
408
  /**
359
- * Прокси для отдельной entity: id отображается как string,
360
- * остальные поля аналогично Palistor<T>.
409
+ * Proxy for a single entity: id is exposed as string,
410
+ * remaining fields follow the Palistor<T> rules.
361
411
  */
362
412
  export type PalistorEntityProxy<T extends {
363
413
  id?: any;
@@ -367,14 +417,14 @@ export type PalistorEntityProxy<T extends {
367
417
  [K in Exclude<keyof T, "id">]: T[K] extends Record<string, any> ? Palistor<T[K]> : FieldProxyNode<T[K]>;
368
418
  };
369
419
  /**
370
- * Маппит интерфейс значений формы на прокси-типы.
371
- * В отличие от ConfigProxy (работает с конфиг-нодами), Palistor
372
- * принимает простой интерфейс значений удобно для типизации пропсов
373
- * дочерних компонентов, получающих поддерево из useForm.
420
+ * Maps a form-values interface onto proxy types.
421
+ * Unlike ConfigProxy (which works with config nodes), Palistor takes a plain
422
+ * values interface convenient for typing props of child components that
423
+ * receive a subtree from useForm.
374
424
  *
375
- * **Важно:** из пакета этот тип экспортируется под именем `PalistorProxy`,
376
- * так как имя `Palistor` занято одноимённым классом.
377
- * Используйте `import type { PalistorProxy } from "palistor"`.
425
+ * **Note:** the package exports this type as `PalistorProxy`, because the
426
+ * name `Palistor` is taken by the class of the same name.
427
+ * Use `import type { PalistorProxy } from "palistor"`.
378
428
  *
379
429
  * @example
380
430
  * ```ts
@@ -392,26 +442,26 @@ export type Palistor<T extends Record<string, any> = {}, M extends FieldMapping
392
442
  [K in keyof T]: T[K] extends Array<infer Item> ? Item extends Record<string, any> ? ApplyFieldMapping<ListProxyNode<Palistor<Item, M>>, M> : ApplyFieldMapping<ListProxyNode<FieldProxyNode<Item>>, M> : T[K] extends Record<string, any> ? Palistor<T[K], M> : ApplyFieldMapping<FieldProxyNode<T[K]>, M>;
393
443
  };
394
444
  /**
395
- * Рекурсивно извлекает типы значений из конфига формы.
396
- * Листовые узлы (содержащие `value`) → тип значения.
397
- * Групповые узлывложенный объект с теми же правилами.
398
- * Служебные ключи (validate, formatter, …) пропускаются.
445
+ * Recursively extracts value types from a form config.
446
+ * Leaf nodes (containing `value`) → the value type.
447
+ * Group nodesa nested object with the same rules.
448
+ * Service keys (validate, formatter, …) are skipped.
399
449
  */
400
450
  export type ExtractValues<T> = {
401
- [K in keyof T as K extends ConfigSkipKeys ? never : K]: T[K] extends readonly [infer Item, ...any[]] ? Array<ExtractValues<Item>> : T[K] extends {
451
+ [K in keyof T as K extends ConfigSkipKeys ? never : K]: [InferFlowSteps<T[K]>] extends [never] ? T[K] extends readonly [infer Item, ...any[]] ? Array<ExtractValues<Item>> : T[K] extends {
402
452
  value: any;
403
- } ? ExtractNodeValue<T[K]> : T[K] extends Record<string, any> ? ExtractValues<T[K]> : never;
453
+ } ? ExtractNodeValue<T[K]> : T[K] extends Record<string, any> ? ExtractValues<T[K]> : never : FlowValues<InferFlowSteps<T[K]>>;
404
454
  };
405
455
  /**
406
- * Карта переименования internal → external для проекции полей через proxy.
456
+ * internal → external rename map for projecting field names through the proxy.
407
457
  *
408
- * Sparse: указываем только те ключи, которые переименовываем; остальные
409
- * остаются с оригинальными именами. Применяется на границе proxy
410
- * (GET/SET/ownKeys/spread) и в tracking-proxy; internal-логика (FieldState,
411
- * compute, pipelines) остаётся неизменной.
458
+ * Sparse: list only the keys you rename; the rest keep their original names.
459
+ * Applied at the proxy boundary (GET/SET/ownKeys/spread) and in the tracking
460
+ * proxy; internal logic (FieldState, compute, pipelines) is unchanged.
412
461
  *
413
- * **Инвариант:** карта биекция. External-имя не должно совпадать с именем
414
- * соседнего дочернего поля и не должно указывать на два разных internal-ключа.
462
+ * **Invariant:** the map is a bijection. An external name must not collide
463
+ * with a sibling child-field name and must not point at two different
464
+ * internal keys.
415
465
  *
416
466
  * @example
417
467
  * fieldMapping: {
@@ -422,85 +472,89 @@ export type ExtractValues<T> = {
422
472
  */
423
473
  export type FieldMapping = Partial<Record<MappableKey, string>>;
424
474
  /**
425
- * Применяет карту переименования `M` (internal → external) к типу прокси-узла `T`:
426
- * каждый ключ `K`, присутствующий в `M`, переименовывается в `M[K]`; остальные
427
- * остаются как есть. Модификаторы (`readonly`, геттер/сеттер `value`) сохраняются.
475
+ * Applies the rename map `M` (internal → external) to a proxy node type `T`:
476
+ * every key `K` present in `M` is renamed to `M[K]`; the rest are unchanged.
477
+ * Modifiers (`readonly`, the `value` getter/setter) are preserved.
428
478
  *
429
- * Пустая карта (`{}`) → identity: возвращается исходный `T` без перестроения,
430
- * поэтому поведение по умолчанию строго совпадает с прежним (нулевой оверхед).
479
+ * An empty map (`{}`) → identity: the original `T` is returned without
480
+ * remapping, so the default behavior matches the pre-mapping one exactly
481
+ * (zero overhead).
431
482
  */
432
483
  export type ApplyFieldMapping<T, M extends FieldMapping> = keyof M extends never ? T : {
433
484
  [K in keyof T as K extends keyof M ? (M[K] extends string ? M[K] : K) : K]: T[K];
434
485
  };
435
486
  declare const CONFIG_KEY_ERROR: unique symbol;
436
- /** Брендированный тип-ошибка: делает свойство неприсваиваемым и выносит текст
437
- * подсказки в сообщение компилятора. */
487
+ /** Branded error type: makes the property unassignable and surfaces the hint
488
+ * text in the compiler message. */
438
489
  export type ConfigKeyError<Msg extends string> = {
439
490
  readonly [CONFIG_KEY_ERROR]: Msg;
440
491
  };
441
- /** Internal-имена config-ключей, которые карта `M` активно переименовывает. */
492
+ /** Internal config key names actively renamed by the map `M`. */
442
493
  type RemappedInternalConfigKey<M extends FieldMapping> = keyof M & MappableConfigKey;
443
494
  /**
444
- * Проверяет дерево конфига `T` против карты `M`: любой узел, содержащий
445
- * INTERNAL-имя ремапленного config-ключа (`isRequired` при `isRequired→required`),
446
- * получает на этом ключе {@link ConfigKeyError} → присваивание падает с читаемым
447
- * текстом. Пустая карта → `unknown` (пересечение-identity, нулевой оверхед).
495
+ * Checks the config tree `T` against the map `M`: any node containing the
496
+ * INTERNAL name of a remapped config key (`isRequired` when `isRequired→required`)
497
+ * gets a {@link ConfigKeyError} on that key the assignment fails with a
498
+ * readable message. Empty map → `unknown` (intersection identity, zero overhead).
448
499
  *
449
- * Пересекается с `TConfig` в опции `config`, поэтому валидные ключи сохраняют
450
- * исходный тип (`T[K] & unknown`), а ошибочные становятся неприсваиваемыми.
500
+ * Intersected with `TConfig` in the `config` option, so valid keys keep their
501
+ * original type (`T[K] & unknown`) while offending ones become unassignable.
451
502
  */
452
503
  export type ValidateExternalConfig<T, M extends FieldMapping> = keyof M extends never ? unknown : T extends object ? {
453
504
  [K in keyof T]: K extends RemappedInternalConfigKey<M> ? ConfigKeyError<`palistor: write "${M[K] & string}" instead of internal "${K & string}" — fieldMapping is active`> : ValidateExternalConfig<T[K], M>;
454
505
  } : unknown;
455
506
  /**
456
- * Тип узла конфига в ЕДИНОМ публичном словаре карты `M` (external-имена).
457
- * Опционально: аннотируйте узел/константу конфига этим типом, чтобы получить
458
- * автокомплит external-имён (`required`, `helpText`, …). Для строгости аннотация
459
- * не обязательнавалидатор в `config` уже ловит internal-имена.
507
+ * Config node type in the SINGLE public vocabulary of the map `M` (external
508
+ * names). Optional: annotate a config node/constant with this type to get
509
+ * autocomplete for external names (`required`, `helpText`, …). Strictness
510
+ * does not require the annotation the validator on `config` already
511
+ * catches internal names.
460
512
  */
461
513
  export type ExternalConfigNode<M extends FieldMapping, TValue = unknown, TValues = Record<string, unknown>> = ApplyFieldMapping<ConfigNode<TValue, TValues>, M>;
462
514
  /**
463
- * Тип конфига формы в external-именах карты `M` (аналог {@link FormConfig}, но с
464
- * переименованными состояниями поля). Для ОПЦИОНАЛЬНОЙ аннотации ради автокомплита
465
- * external-имён.
515
+ * Form config type in the external names of the map `M` (like {@link FormConfig},
516
+ * but with renamed field-state keys). For OPTIONAL annotation, purely for
517
+ * external-name autocomplete.
466
518
  *
467
- * ⚠️ Компромисс: это `Record<string, …>` (как {@link FormConfig}), поэтому
468
- * аннотация расширяет тип литерала и `ExtractValues`/типизация `initialValues`
469
- * теряют точность. Рекомендуемый путь **не аннотировать**: валидатор в опции
470
- * `config` (см. {@link ValidateExternalConfig}) и так ловит internal-имена, а
471
- * точный вывод значений полей из литерала сохраняется. Аннотацию используйте
472
- * только там, где точный `ExtractValues` не нужен.
519
+ * ⚠️ Trade-off: this is a `Record<string, …>` (like {@link FormConfig}), so
520
+ * the annotation widens the literal type and `ExtractValues`/`initialValues`
521
+ * typing lose precision. The recommended path is to **not annotate**: the
522
+ * validator on the `config` option (see {@link ValidateExternalConfig})
523
+ * already catches internal names, while precise value inference from the
524
+ * literal is preserved. Use the annotation only where precise `ExtractValues`
525
+ * is not needed.
473
526
  */
474
527
  export type ExternalConfig<M extends FieldMapping, TValues = Record<string, unknown>> = Record<string, ExternalConfigNode<M, any, TValues>>;
475
528
  export interface ProxyStoreOptions<TConfig extends Record<string, any>, TMapping extends FieldMapping = {}> {
476
529
  /**
477
- * Декларативное описание структуры и полей формы. Остаётся неизменяемым.
530
+ * Declarative description of the form structure and fields. Never mutated.
478
531
  *
479
- * При активном `fieldMapping` конфиг пишется в ЕДИНОМ публичном словаре карты
480
- * (external-имена: `required`, `helpText`, …). Пересечение с
481
- * {@link ValidateExternalConfig} ловит internal-имена (`isRequired`, …) как
482
- * ошибку типа с подсказкой. `NoInfer` не даёт `TMapping` «протечь» из конфига —
483
- * карта выводится только из `fieldMapping`.
532
+ * When `fieldMapping` is active, the config is written in the map's SINGLE
533
+ * public vocabulary (external names: `required`, `helpText`, …). The
534
+ * intersection with {@link ValidateExternalConfig} catches internal names
535
+ * (`isRequired`, …) as a type error with a hint. `NoInfer` prevents
536
+ * `TMapping` from leaking out of the config — the map is inferred from
537
+ * `fieldMapping` only.
484
538
  */
485
539
  config: TConfig & ValidateExternalConfig<TConfig, NoInfer<TMapping>>;
486
540
  /**
487
- * Стартовые значения, которые перекрывают значения по умолчанию из конфига.
488
- * Структура совпадает со структурой конфига, но все поля опциональны.
541
+ * Initial values that override the defaults from the config.
542
+ * Mirrors the config structure, but all fields are optional.
489
543
  */
490
544
  initialValues?: DeepPartialValues<ExtractValues<TConfig>>;
491
545
  /**
492
- * Начальный контекст. Если передан, eager resolvers увидят его при первом запуске.
493
- * Аналогично вызову `setContext()` до `launchEager()`.
546
+ * Initial context. When provided, eager resolvers see it on their first run.
547
+ * Equivalent to calling `setContext()` before `launchEager()`.
494
548
  */
495
549
  context?: Record<string, unknown>;
496
550
  /**
497
- * Необязательная карта переименования internal → external. Задаёт, под какими
498
- * именами внутренние свойства поля видны через proxy (GET + ownKeys/spread +
499
- * tracking). Если не передан поведение и производительность без изменений.
551
+ * Optional internal → external rename map. Defines the names under which
552
+ * internal field properties are visible through the proxy (GET + ownKeys/
553
+ * spread + tracking). When omitted, behavior and performance are unchanged.
500
554
  *
501
- * Тип литерала карты захватывается (через `const`-параметр класса Palistor) и
502
- * прокидывается в тип `store.proxy` / `useForm(store)`, поэтому переименованные
503
- * имена типизируются статическибез `as any`.
555
+ * The map's literal type is captured (via the Palistor class `const` type
556
+ * parameter) and threaded into the `store.proxy` / `useForm(store)` types,
557
+ * so renamed names are statically typed no `as any`.
504
558
  *
505
559
  * @see FieldMapping
506
560
  */
@@ -508,86 +562,86 @@ export interface ProxyStoreOptions<TConfig extends Record<string, any>, TMapping
508
562
  }
509
563
  export interface ProxyStore<TConfig extends Record<string, any>, TMapping extends FieldMapping = {}> {
510
564
  /**
511
- * @internal Обратная карта переименования external → internal (sparse).
512
- * Используется на входе proxy (GET/SET/tracking): приходящий external-ключ
513
- * переводится в internal одной строкой. Пустая, если `fieldMapping` не задан.
565
+ * @internal Reverse rename map, external → internal (sparse).
566
+ * Used on proxy input (GET/SET/tracking): an incoming external key is
567
+ * translated to internal in one lookup. Empty when `fieldMapping` is unset.
514
568
  */
515
569
  readonly externalToInternal: Record<string, string>;
516
570
  /**
517
- * Реактивный прокси. Повторяет структуру конфига.
518
- * GET .value / .isVisible / … → из вычисленного FieldState
571
+ * Reactive proxy. Mirrors the config structure.
572
+ * GET .value / .isVisible / … → from the computed FieldState
519
573
  * SET .value = X → formatter → validate → recompute → notify
520
574
  *
521
- * Имена свойств спроецированы согласно `TMapping` (см. {@link FieldMapping}).
575
+ * Property names are projected according to `TMapping` (see {@link FieldMapping}).
522
576
  *
523
- * Тип помечен {@link RawStoreProxyMarker} — этот узел и все его поддеревья
524
- * **нельзя** передавать в `useForm()` (ни на root-, ни на subtree-уровне).
525
- * Для подписки в React используйте `useForm(store)` и обращайтесь к
526
- * полям через возвращённый tracking-proxy.
577
+ * The type carries {@link RawStoreProxyMarker} — this node and all of its
578
+ * subtrees must **not** be passed to `useForm()` (neither root nor subtree).
579
+ * To subscribe in React, use `useForm(store)` and access fields through the
580
+ * returned tracking proxy.
527
581
  */
528
582
  proxy: RawStoreProxy<TConfig, TMapping>;
529
583
  /**
530
- * Нереактивный контекстпроизвольные данные, доступные во всех callback-ах
531
- * (resolve.resolver, onSubmit, onChange, …) через `store.context`.
584
+ * Non-reactive contextarbitrary data available in all callbacks
585
+ * (resolve.resolver, onSubmit, onChange, …) via `store.context`.
532
586
  *
533
- * Устанавливается через `setContext()` или хук `useStoreContext()`.
534
- * Не является частью формыне попадает в getValues(), submit, persist.
587
+ * Set via `setContext()` or the `useStoreContext()` hook.
588
+ * Not part of the form excluded from getValues(), submit, persist.
535
589
  *
536
590
  * @example
537
591
  * store.context.accountId; // read
538
592
  */
539
593
  readonly context: Record<string, unknown>;
540
594
  /**
541
- * Установить нереактивный контекст. Заменяет текущий context целиком.
542
- * Вызывается из React (useStoreContext) или императивно.
595
+ * Sets the non-reactive context. Replaces the current context wholesale.
596
+ * Called from React (useStoreContext) or imperatively.
543
597
  *
544
598
  * @example
545
599
  * store.setContext({ accountId: "abc", tenant: "acme" });
546
600
  */
547
601
  setContext(ctx: Record<string, unknown>): void;
548
602
  /**
549
- * Подписаться на изменение состояния конкретного узла конфига.
550
- * Возвращает функцию-отписку.
603
+ * Subscribes to state changes of a specific config node.
604
+ * Returns an unsubscribe function.
551
605
  */
552
606
  subscribe: (node: object, listener: () => void) => Unsubscribe;
553
607
  /**
554
- * Подписаться на ЛЮБОЕ изменение в хранилище.
555
- * Используется useForm для useSyncExternalStore.
556
- * Возвращает функцию-отписку.
608
+ * Subscribes to ANY store change.
609
+ * Used by useForm for useSyncExternalStore.
610
+ * Returns an unsubscribe function.
557
611
  */
558
612
  subscribeGlobal: (listener: () => void) => Unsubscribe;
559
613
  /**
560
- * Глобальная версия хранилища. Инкрементируется при каждом изменении.
561
- * Используется как snapshot для useSyncExternalStore.
614
+ * Global store version. Incremented on every change.
615
+ * Used as the snapshot for useSyncExternalStore.
562
616
  */
563
617
  getVersion: () => number;
564
618
  /**
565
- * Версия конкретного узла. Обновляется при изменении состояния узла.
566
- * Используется для точечной подписки (re-render только по прочитанным полям).
619
+ * Version of a specific node. Bumped when the node's state changes.
620
+ * Used for targeted subscriptions (re-render only on fields actually read).
567
621
  */
568
622
  getNodeVersion: (node: object) => number;
569
623
  /**
570
- * Все текущие значения полей в виде вложенного объекта.
624
+ * All current field values as a nested object.
571
625
  */
572
626
  getValues: () => ExtractValues<TConfig>;
573
627
  /**
574
- * Регистрирует функцию перевода (next-intl, i18next, …) для резолва
628
+ * Registers a translation function (next-intl, i18next, …) for resolving
575
629
  * label / placeholder / description.
576
630
  *
577
- * При смене транслятора все подписанные компоненты перерендерятся
578
- * с актуальными переводами.
631
+ * When the translator changes, all subscribed components re-render with
632
+ * up-to-date translations.
579
633
  *
580
- * @param t — функция перевода или null для сброса
634
+ * @param t — translation function, or null to clear
581
635
  */
582
636
  setTranslator: (t: TranslateFn | null) => void;
583
637
  /**
584
- * Менеджер персистенциигидратация и автосохранение состояния формы.
638
+ * Persistence managerhydration and auto-saving of form state.
585
639
  */
586
640
  persist: PersistManager;
587
641
  /**
588
- * Регистрирует функцию уведомления (toast, alert, …) для resolver onError.
642
+ * Registers a notification function (toast, alert, …) for resolver onError.
589
643
  *
590
- * @param fn — функция уведомления или null для сброса
644
+ * @param fn — notification function, or null to clear
591
645
  */
592
646
  setNotifier: (fn: NotifyFn | null) => void;
593
647
  /**
@@ -596,26 +650,26 @@ export interface ProxyStore<TConfig extends Record<string, any>, TMapping extend
596
650
  */
597
651
  submit(): Promise<SubmitResult>;
598
652
  /**
599
- * Reset root form к defaults из конфига (или к переданным значениям).
653
+ * Resets the root form to config defaults (or to the provided values).
600
654
  */
601
655
  reset(values?: DeepPartialValues<ExtractValues<TConfig>>): void;
602
656
  /**
603
- * Bulk-обновление значений: применяет патч ко всему store за один recompute + notify.
604
- * Без setters (чтобы избежать рекурсии) и без форматтеров.
605
- * Используется для подлива серверных данных или bulk-изменений из React.
657
+ * Bulk value update: applies a patch to the whole store in a single recompute + notify.
658
+ * Skips setters (to avoid recursion) and formatters.
659
+ * Used for feeding in server data or bulk changes from React.
606
660
  */
607
661
  setValues(patch: DeepPartialValues<ExtractValues<TConfig>>): void;
608
662
  /**
609
- * Создать или обновить entity (или массив entities) в реестре.
610
- * - Если entity с таким id не существует создаётся, leaf-ноды регистрируются.
611
- * - Если существуетрекурсивный merge; изменённые leaf-ноды уведомляются.
612
- * - Batch-режим: массив обрабатывается одним recompute + notifyChanged.
663
+ * Creates or updates an entity (or an array of entities) in the registry.
664
+ * - If no entity with the id existsit is created and its leaf nodes registered.
665
+ * - If it exists recursive merge; changed leaf nodes are notified.
666
+ * - Batch mode: an array is processed in one recompute + notifyChanged.
613
667
  */
614
668
  set(data: import("../entityRegistry").EntityData | import("../entityRegistry").EntityData[]): void;
615
669
  /**
616
- * Удалить entity из реестра по ID.
617
- * Очищает leaf-ноды, bindings и resolvedCache. Уведомляет подписчиков.
618
- * No-op если entity не существует.
670
+ * Deletes an entity from the registry by ID.
671
+ * Clears leaf nodes, bindings and resolvedCache. Notifies subscribers.
672
+ * No-op when the entity does not exist.
619
673
  */
620
674
  delete(id: string): void;
621
675
  }