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.
- package/README.md +574 -542
- package/README.ru.md +979 -0
- package/dist/index.d.ts +19 -28
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +21 -28
- package/dist/index.js.map +1 -1
- package/dist/react/createTrackingProxy.d.ts +27 -27
- package/dist/react/createTrackingProxy.d.ts.map +1 -1
- package/dist/react/createTrackingProxy.js +92 -42
- package/dist/react/createTrackingProxy.js.map +1 -1
- package/dist/react/useForm.d.ts +42 -43
- package/dist/react/useForm.d.ts.map +1 -1
- package/dist/react/useForm.js +38 -38
- package/dist/react/useForm.js.map +1 -1
- package/dist/react/usePersist.d.ts +14 -14
- package/dist/react/usePersist.js +18 -18
- package/dist/react/usePersist.js.map +1 -1
- package/dist/react/useStoreContext.d.ts +11 -11
- package/dist/react/useStoreContext.js +11 -11
- package/dist/react/useTranslator.d.ts +12 -12
- package/dist/react/useTranslator.js +12 -12
- package/dist/store/applyPatch/applyPatch.d.ts +8 -8
- package/dist/store/applyPatch/applyPatch.js +12 -12
- package/dist/store/applyPatch/applyPatch.js.map +1 -1
- package/dist/store/buildProxy/buildEntityProjectionProxy.js +6 -6
- package/dist/store/buildProxy/buildEntityProjectionProxy.js.map +1 -1
- package/dist/store/buildProxy/buildListProxy.d.ts +8 -8
- package/dist/store/buildProxy/buildListProxy.js +30 -30
- package/dist/store/buildProxy/buildListProxy.js.map +1 -1
- package/dist/store/buildProxy/buildProxy.d.ts +8 -8
- package/dist/store/buildProxy/buildProxy.d.ts.map +1 -1
- package/dist/store/buildProxy/buildProxy.js +84 -33
- package/dist/store/buildProxy/buildProxy.js.map +1 -1
- package/dist/store/buildProxy/computeProxyKeys.d.ts +8 -8
- package/dist/store/buildProxy/computeProxyKeys.d.ts.map +1 -1
- package/dist/store/buildProxy/computeProxyKeys.js +18 -13
- package/dist/store/buildProxy/computeProxyKeys.js.map +1 -1
- package/dist/store/buildProxy/handleLazyResolve.d.ts +3 -3
- package/dist/store/buildProxy/handleLazyResolve.js +3 -3
- package/dist/store/buildProxy/initProxyCaches.d.ts +5 -5
- package/dist/store/buildProxy/initProxyCaches.js +5 -5
- package/dist/store/compute/computeFieldState.d.ts +3 -3
- package/dist/store/compute/computeFieldState.js +8 -8
- package/dist/store/compute/computeFieldState.js.map +1 -1
- package/dist/store/compute/fieldStateChanged.d.ts +1 -1
- package/dist/store/compute/fieldStateChanged.js +1 -1
- package/dist/store/compute/recompute/collectGroupComputeNodes.d.ts +4 -4
- package/dist/store/compute/recompute/collectGroupComputeNodes.js +7 -7
- package/dist/store/compute/recompute/collectGroupComputeNodes.js.map +1 -1
- package/dist/store/compute/recompute/recomputeAndNotify.d.ts +3 -3
- package/dist/store/compute/recompute/recomputeAndNotify.js +3 -3
- package/dist/store/compute/recompute/recomputeLeaves.d.ts +11 -10
- package/dist/store/compute/recompute/recomputeLeaves.d.ts.map +1 -1
- package/dist/store/compute/recompute/recomputeLeaves.js +26 -27
- package/dist/store/compute/recompute/recomputeLeaves.js.map +1 -1
- package/dist/store/compute/recompute/recomputeTargeted.d.ts +7 -7
- package/dist/store/compute/recompute/recomputeTargeted.js +12 -12
- package/dist/store/compute/recompute/recomputeTargeted.js.map +1 -1
- package/dist/store/compute/recompute/topologicalSortComputed.d.ts +4 -4
- package/dist/store/compute/recompute/topologicalSortComputed.d.ts.map +1 -1
- package/dist/store/compute/recompute/topologicalSortComputed.js +11 -13
- package/dist/store/compute/recompute/topologicalSortComputed.js.map +1 -1
- package/dist/store/compute/recompute/types.d.ts +4 -4
- package/dist/store/compute/resolveFlag.d.ts +2 -2
- package/dist/store/compute/resolveFlag.js +2 -2
- package/dist/store/compute/resolveString.d.ts +5 -5
- package/dist/store/compute/resolveString.js +6 -6
- package/dist/store/compute/resolveString.js.map +1 -1
- package/dist/store/compute/types.d.ts +3 -3
- package/dist/store/constants.d.ts +57 -38
- package/dist/store/constants.d.ts.map +1 -1
- package/dist/store/constants.js +70 -35
- package/dist/store/constants.js.map +1 -1
- package/dist/store/defineFieldMapping.d.ts +21 -19
- package/dist/store/defineFieldMapping.d.ts.map +1 -1
- package/dist/store/defineFieldMapping.js +21 -19
- package/dist/store/defineFieldMapping.js.map +1 -1
- package/dist/store/dirtyTracking/collectInitialSnapshot.js +1 -1
- package/dist/store/dirtyTracking/collectInitialSnapshot.js.map +1 -1
- package/dist/store/dirtyTracking/recomputeDirtyTargeted.d.ts +3 -3
- package/dist/store/dirtyTracking/recomputeDirtyTargeted.js +11 -11
- package/dist/store/dirtyTracking/recomputeDirtyTargeted.js.map +1 -1
- package/dist/store/dirtyTracking/setGroupRevalidate.d.ts +6 -6
- package/dist/store/dirtyTracking/setGroupRevalidate.js +7 -7
- package/dist/store/dirtyTracking/setGroupRevalidate.js.map +1 -1
- package/dist/store/entityRegistry/entityRegistry.d.ts +72 -72
- package/dist/store/entityRegistry/entityRegistry.d.ts.map +1 -1
- package/dist/store/entityRegistry/entityRegistry.js +91 -91
- package/dist/store/entityRegistry/entityRegistry.js.map +1 -1
- package/dist/store/entityRegistry/generateId.d.ts +3 -3
- package/dist/store/entityRegistry/generateId.js +3 -3
- package/dist/store/entityRegistry/types.d.ts +17 -17
- package/dist/store/entityRegistry/types.d.ts.map +1 -1
- package/dist/store/flow/buildFlowStepsProxy.d.ts +17 -0
- package/dist/store/flow/buildFlowStepsProxy.d.ts.map +1 -0
- package/dist/store/flow/buildFlowStepsProxy.js +72 -0
- package/dist/store/flow/buildFlowStepsProxy.js.map +1 -0
- package/dist/store/flow/defineFlow.d.ts +92 -0
- package/dist/store/flow/defineFlow.d.ts.map +1 -0
- package/dist/store/flow/defineFlow.js +99 -0
- package/dist/store/flow/defineFlow.js.map +1 -0
- package/dist/store/flow/flowApi.d.ts +18 -0
- package/dist/store/flow/flowApi.d.ts.map +1 -0
- package/dist/store/flow/flowApi.js +18 -0
- package/dist/store/flow/flowApi.js.map +1 -0
- package/dist/store/flow/flowNavigation.d.ts +137 -0
- package/dist/store/flow/flowNavigation.d.ts.map +1 -0
- package/dist/store/flow/flowNavigation.js +384 -0
- package/dist/store/flow/flowNavigation.js.map +1 -0
- package/dist/store/flow/flowState.d.ts +41 -0
- package/dist/store/flow/flowState.d.ts.map +1 -0
- package/dist/store/flow/flowState.js +51 -0
- package/dist/store/flow/flowState.js.map +1 -0
- package/dist/store/flow/index.d.ts +10 -0
- package/dist/store/flow/index.d.ts.map +1 -0
- package/dist/store/flow/index.js +6 -0
- package/dist/store/flow/index.js.map +1 -0
- package/dist/store/groupDeps/createGroupDeps.d.ts +3 -3
- package/dist/store/groupDeps/createGroupDeps.js +6 -6
- package/dist/store/groupDeps/createGroupDeps.js.map +1 -1
- package/dist/store/groupDeps/createTrackingValues.d.ts +9 -9
- package/dist/store/groupDeps/createTrackingValues.js +11 -11
- package/dist/store/groupDeps/createTrackingValues.js.map +1 -1
- package/dist/store/groupDeps/getNodeGroupPath.d.ts +3 -3
- package/dist/store/groupDeps/getNodeGroupPath.js +5 -5
- package/dist/store/groupDeps/getNodeGroupPath.js.map +1 -1
- package/dist/store/groupDeps/getRecipientGroups.d.ts +1 -1
- package/dist/store/groupDeps/getRecipientGroups.js +1 -1
- package/dist/store/groupDeps/groupDeps.d.ts +7 -7
- package/dist/store/groupDeps/groupDeps.js +7 -7
- package/dist/store/groupDeps/pairKey.d.ts +3 -3
- package/dist/store/groupDeps/pairKey.d.ts.map +1 -1
- package/dist/store/groupDeps/pairKey.js +4 -4
- package/dist/store/groupDeps/pairKey.js.map +1 -1
- package/dist/store/groupDeps/resolveGroupByPath.d.ts +3 -3
- package/dist/store/groupDeps/resolveGroupByPath.js +3 -3
- package/dist/store/init/createNotificationHub.d.ts +31 -31
- package/dist/store/init/createNotificationHub.d.ts.map +1 -1
- package/dist/store/init/createNotificationHub.js +36 -37
- package/dist/store/init/createNotificationHub.js.map +1 -1
- package/dist/store/init/createResolveManager.d.ts +72 -69
- package/dist/store/init/createResolveManager.d.ts.map +1 -1
- package/dist/store/init/createResolveManager.js +101 -98
- package/dist/store/init/createResolveManager.js.map +1 -1
- package/dist/store/init/initGroupSubmitting.d.ts +2 -2
- package/dist/store/init/initGroupSubmitting.js +4 -4
- package/dist/store/init/initGroupSubmitting.js.map +1 -1
- package/dist/store/normalizeConfig.d.ts +20 -18
- package/dist/store/normalizeConfig.d.ts.map +1 -1
- package/dist/store/normalizeConfig.js +31 -29
- package/dist/store/normalizeConfig.js.map +1 -1
- package/dist/store/onChangePipeline/computeFieldKey.d.ts +2 -2
- package/dist/store/onChangePipeline/computeFieldKey.js +2 -2
- package/dist/store/onChangePipeline/findOnChangeAncestors.d.ts +2 -2
- package/dist/store/onChangePipeline/findOnChangeAncestors.js +4 -4
- package/dist/store/onChangePipeline/findOnChangeAncestors.js.map +1 -1
- package/dist/store/onChangePipeline/onChangePipeline.d.ts +13 -12
- package/dist/store/onChangePipeline/onChangePipeline.d.ts.map +1 -1
- package/dist/store/onChangePipeline/onChangePipeline.js +14 -13
- package/dist/store/onChangePipeline/onChangePipeline.js.map +1 -1
- package/dist/store/persist/drivers.d.ts +7 -7
- package/dist/store/persist/drivers.js +8 -8
- package/dist/store/persist/drivers.js.map +1 -1
- package/dist/store/persist/index.d.ts +1 -1
- package/dist/store/persist/persistManager.d.ts +23 -23
- package/dist/store/persist/persistManager.d.ts.map +1 -1
- package/dist/store/persist/persistManager.js +73 -42
- package/dist/store/persist/persistManager.js.map +1 -1
- package/dist/store/persist/types.d.ts +23 -23
- package/dist/store/persist/types.d.ts.map +1 -1
- package/dist/store/persist/types.js +4 -4
- package/dist/store/resetPipeline/buildResetPatch.d.ts +5 -5
- package/dist/store/resetPipeline/buildResetPatch.js +5 -5
- package/dist/store/resetPipeline/collectDefaults.d.ts +5 -5
- package/dist/store/resetPipeline/collectDefaults.js +6 -6
- package/dist/store/resetPipeline/collectDefaults.js.map +1 -1
- package/dist/store/resetPipeline/resetPipeline.d.ts +7 -7
- package/dist/store/resetPipeline/resetPipeline.d.ts.map +1 -1
- package/dist/store/resetPipeline/resetPipeline.js +17 -12
- package/dist/store/resetPipeline/resetPipeline.js.map +1 -1
- package/dist/store/resolvePipeline/applyPendingWrites.d.ts +10 -10
- package/dist/store/resolvePipeline/applyPendingWrites.d.ts.map +1 -1
- package/dist/store/resolvePipeline/applyPendingWrites.js +35 -38
- package/dist/store/resolvePipeline/applyPendingWrites.js.map +1 -1
- package/dist/store/resolvePipeline/createContextTrackingProxy.d.ts +8 -7
- package/dist/store/resolvePipeline/createContextTrackingProxy.d.ts.map +1 -1
- package/dist/store/resolvePipeline/createContextTrackingProxy.js +6 -5
- package/dist/store/resolvePipeline/createContextTrackingProxy.js.map +1 -1
- package/dist/store/resolvePipeline/createValuesTrackingProxy.d.ts +43 -43
- package/dist/store/resolvePipeline/createValuesTrackingProxy.d.ts.map +1 -1
- package/dist/store/resolvePipeline/createValuesTrackingProxy.js +70 -70
- package/dist/store/resolvePipeline/createValuesTrackingProxy.js.map +1 -1
- package/dist/store/resolvePipeline/executeListResolve.d.ts +14 -14
- package/dist/store/resolvePipeline/executeListResolve.js +27 -27
- package/dist/store/resolvePipeline/executeListResolve.js.map +1 -1
- package/dist/store/resolvePipeline/executeResolve.d.ts +15 -15
- package/dist/store/resolvePipeline/executeResolve.js +46 -46
- package/dist/store/resolvePipeline/executeResolve.js.map +1 -1
- package/dist/store/store/NodeRegistry/nodeRegistry.d.ts +69 -56
- package/dist/store/store/NodeRegistry/nodeRegistry.d.ts.map +1 -1
- package/dist/store/store/NodeRegistry/nodeRegistry.js +94 -78
- package/dist/store/store/NodeRegistry/nodeRegistry.js.map +1 -1
- package/dist/store/store/NodeRegistry/nodeUtils.d.ts +5 -5
- package/dist/store/store/NodeRegistry/nodeUtils.d.ts.map +1 -1
- package/dist/store/store/NodeRegistry/nodeUtils.js +5 -5
- package/dist/store/store/NodeRegistry/nodeUtils.js.map +1 -1
- package/dist/store/store/groupDepsMap.d.ts +23 -23
- package/dist/store/store/groupDepsMap.d.ts.map +1 -1
- package/dist/store/store/groupDepsMap.js +40 -34
- package/dist/store/store/groupDepsMap.js.map +1 -1
- package/dist/store/store/hasComputedProps.d.ts +2 -2
- package/dist/store/store/hasComputedProps.js +2 -2
- package/dist/store/store/nodeMap.d.ts +5 -5
- package/dist/store/store/nodeMap.js +7 -7
- package/dist/store/store/nodeMap.js.map +1 -1
- package/dist/store/store/palistor.d.ts +80 -80
- package/dist/store/store/palistor.d.ts.map +1 -1
- package/dist/store/store/palistor.js +151 -165
- package/dist/store/store/palistor.js.map +1 -1
- package/dist/store/store/registerNodes.d.ts +10 -10
- package/dist/store/store/registerNodes.d.ts.map +1 -1
- package/dist/store/store/registerNodes.js +33 -18
- package/dist/store/store/registerNodes.js.map +1 -1
- package/dist/store/store/serviceRegistry.d.ts +8 -8
- package/dist/store/store/serviceRegistry.d.ts.map +1 -1
- package/dist/store/store/serviceRegistry.js +8 -8
- package/dist/store/store/serviceRegistry.js.map +1 -1
- package/dist/store/store/types.d.ts +277 -223
- package/dist/store/store/types.d.ts.map +1 -1
- package/dist/store/submitPipeline/applyLeafBeforeSubmit.d.ts +2 -2
- package/dist/store/submitPipeline/applyLeafBeforeSubmit.js +2 -2
- package/dist/store/submitPipeline/collectLeafStates.d.ts +2 -2
- package/dist/store/submitPipeline/collectLeafStates.js +2 -2
- package/dist/store/submitPipeline/submitPipeline.d.ts +8 -8
- package/dist/store/submitPipeline/submitPipeline.d.ts.map +1 -1
- package/dist/store/submitPipeline/submitPipeline.js +15 -11
- package/dist/store/submitPipeline/submitPipeline.js.map +1 -1
- package/dist/store/submitPipeline/types.d.ts +1 -1
- package/dist/store/submitPipeline/types.d.ts.map +1 -1
- package/dist/store/traversal/nodeClassifier.d.ts +9 -9
- package/dist/store/traversal/nodeClassifier.d.ts.map +1 -1
- package/dist/store/traversal/nodeClassifier.js +11 -11
- package/dist/store/traversal/nodeClassifier.js.map +1 -1
- package/dist/store/traversal/walkFull.d.ts +14 -14
- package/dist/store/traversal/walkFull.js +2 -2
- package/dist/store/valuesCache/valuesCache.d.ts +9 -9
- package/dist/store/valuesCache/valuesCache.d.ts.map +1 -1
- package/dist/store/valuesCache/valuesCache.js +6 -6
- package/dist/store/writePipeline/formatPatch.d.ts +5 -5
- package/dist/store/writePipeline/formatPatch.js +7 -7
- package/dist/store/writePipeline/formatPatch.js.map +1 -1
- package/dist/store/writePipeline/formatValue.d.ts +5 -5
- package/dist/store/writePipeline/formatValue.js +5 -5
- package/dist/store/writePipeline/mergeChanged.d.ts +4 -4
- package/dist/store/writePipeline/mergeChanged.js +4 -4
- package/dist/store/writePipeline/runSetter.d.ts +6 -6
- package/dist/store/writePipeline/runSetter.js +8 -8
- package/dist/store/writePipeline/storeValue.d.ts +3 -3
- package/dist/store/writePipeline/storeValue.js +3 -3
- package/dist/store/writePipeline/types.d.ts +4 -4
- package/dist/store/writePipeline/types.d.ts.map +1 -1
- package/dist/store/writePipeline/writePipeline.d.ts +7 -7
- package/dist/store/writePipeline/writePipeline.d.ts.map +1 -1
- package/dist/store/writePipeline/writePipeline.js +15 -15
- package/dist/store/writePipeline/writePipeline.js.map +1 -1
- package/package.json +11 -4
- package/dist/store/compute/recompute/collectGroupLeafNodes.d.ts +0 -11
- package/dist/store/compute/recompute/collectGroupLeafNodes.d.ts.map +0 -1
- package/dist/store/compute/recompute/collectGroupLeafNodes.js +0 -26
- package/dist/store/compute/recompute/collectGroupLeafNodes.js.map +0 -1
- package/dist/store/fieldMapping.typecheck.d.ts +0 -2
- package/dist/store/fieldMapping.typecheck.d.ts.map +0 -1
- package/dist/store/fieldMapping.typecheck.js +0 -71
- package/dist/store/fieldMapping.typecheck.js.map +0 -1
- package/dist/store/submitPipeline/getSubValues.d.ts +0 -9
- package/dist/store/submitPipeline/getSubValues.d.ts.map +0 -1
- package/dist/store/submitPipeline/getSubValues.js +0 -26
- 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
|
-
*
|
|
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
|
-
*
|
|
13
|
-
* label/placeholder/description
|
|
14
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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 node — describes both a field and a group.
|
|
67
68
|
*
|
|
68
|
-
*
|
|
69
|
-
* -
|
|
70
|
-
* -
|
|
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
|
-
*
|
|
73
|
-
*
|
|
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 —
|
|
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
|
-
*
|
|
85
|
-
* `false`
|
|
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
|
-
/**
|
|
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
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
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
|
-
/**
|
|
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
|
-
/**
|
|
111
|
+
/** Post-processing after a successful onSubmit. */
|
|
111
112
|
afterSubmit?: (result: unknown, actions: {
|
|
112
113
|
reset: () => void;
|
|
113
114
|
}) => void | Promise<void>;
|
|
114
|
-
/**
|
|
115
|
+
/** Reset transformer: receives defaults, returns the final values. */
|
|
115
116
|
reset?: (defaults: TValues) => TValues;
|
|
116
117
|
/**
|
|
117
|
-
*
|
|
118
|
-
*
|
|
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
|
-
*
|
|
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
|
-
/**
|
|
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
|
|
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
|
|
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
|
-
*
|
|
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
|
|
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
|
|
186
|
+
/** true when at least one field in the group differs from its initial value. */
|
|
187
187
|
readonly dirty: boolean;
|
|
188
188
|
/**
|
|
189
|
-
* true
|
|
190
|
-
* false
|
|
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
|
-
/**
|
|
197
|
+
/** Resets the subtree to config defaults (or to the provided values). */
|
|
198
198
|
reset(values?: Record<string, unknown>): void;
|
|
199
199
|
/**
|
|
200
|
-
* Bulk
|
|
201
|
-
*
|
|
202
|
-
*
|
|
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
|
-
*
|
|
208
|
-
*
|
|
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
|
-
*
|
|
232
|
-
*
|
|
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
|
-
*
|
|
238
|
+
* Internal list state — the SINGLE "list" building block (root + per-entity).
|
|
239
239
|
*
|
|
240
|
-
*
|
|
241
|
-
*
|
|
242
|
-
* per-entity
|
|
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
|
|
245
|
-
* per-entity
|
|
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
|
-
/**
|
|
248
|
+
/** The array config node [template, listConfig?] — key in all registries. */
|
|
249
249
|
listConfigNode: object;
|
|
250
|
-
/**
|
|
250
|
+
/** Item template — describes the fields to render. listConfigNode[0]. */
|
|
251
251
|
template: object;
|
|
252
|
-
/**
|
|
252
|
+
/** List configuration (resolve etc.). listConfigNode[1] — optional. */
|
|
253
253
|
listConfig?: ListConfig;
|
|
254
|
-
/**
|
|
254
|
+
/** List owner. `null` = root list; otherwise the owning entity. */
|
|
255
255
|
ownerEntity: EntityNode | null;
|
|
256
|
-
/**
|
|
256
|
+
/** IDs of the entities in the list (in display order). */
|
|
257
257
|
itemIds: string[];
|
|
258
|
-
/**
|
|
258
|
+
/** Captured at init/resolve — used for membership dirty-tracking. */
|
|
259
259
|
initialItemIds: string[];
|
|
260
260
|
}
|
|
261
261
|
/**
|
|
262
|
-
*
|
|
263
|
-
* TItem —
|
|
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
|
|
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
|
|
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
|
-
/**
|
|
286
|
+
/** Typed entity list. */
|
|
287
287
|
export type PalistorList<T extends Record<string, any>> = ListProxyNode<PalistorRef<T>>;
|
|
288
|
-
/**
|
|
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:
|
|
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
|
-
/**
|
|
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 (
|
|
304
|
-
* -
|
|
305
|
-
* -
|
|
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 = {}> =
|
|
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
|
-
*
|
|
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`
|
|
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
|
-
*
|
|
327
|
-
* `useForm()` —
|
|
328
|
-
*
|
|
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
|
-
*
|
|
335
|
-
*
|
|
336
|
-
*
|
|
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 = {}> =
|
|
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
|
-
*
|
|
347
|
-
*
|
|
348
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
360
|
-
*
|
|
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
|
-
*
|
|
372
|
-
*
|
|
373
|
-
*
|
|
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
|
-
*
|
|
376
|
-
*
|
|
377
|
-
*
|
|
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
|
-
*
|
|
397
|
-
*
|
|
398
|
-
*
|
|
445
|
+
* Recursively extracts value types from a form config.
|
|
446
|
+
* Leaf nodes (containing `value`) → the value type.
|
|
447
|
+
* Group nodes → a 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
|
-
*
|
|
456
|
+
* internal → external rename map for projecting field names through the proxy.
|
|
407
457
|
*
|
|
408
|
-
* Sparse:
|
|
409
|
-
*
|
|
410
|
-
*
|
|
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
|
-
*
|
|
414
|
-
*
|
|
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
|
-
*
|
|
426
|
-
*
|
|
427
|
-
*
|
|
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
|
-
*
|
|
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
|
|
492
|
+
/** Internal config key names actively renamed by the map `M`. */
|
|
442
493
|
type RemappedInternalConfigKey<M extends FieldMapping> = keyof M & MappableConfigKey;
|
|
443
494
|
/**
|
|
444
|
-
*
|
|
445
|
-
* INTERNAL
|
|
446
|
-
*
|
|
447
|
-
*
|
|
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
|
-
*
|
|
450
|
-
*
|
|
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
|
-
*
|
|
457
|
-
*
|
|
458
|
-
*
|
|
459
|
-
*
|
|
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
|
-
*
|
|
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
|
-
* ⚠️
|
|
468
|
-
*
|
|
469
|
-
*
|
|
470
|
-
* `config` (
|
|
471
|
-
*
|
|
472
|
-
*
|
|
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
|
-
*
|
|
480
|
-
* (external
|
|
481
|
-
* {@link ValidateExternalConfig}
|
|
482
|
-
*
|
|
483
|
-
*
|
|
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
|
-
*
|
|
493
|
-
*
|
|
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
|
-
*
|
|
498
|
-
*
|
|
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
|
-
*
|
|
502
|
-
*
|
|
503
|
-
*
|
|
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
|
|
512
|
-
*
|
|
513
|
-
*
|
|
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 / … →
|
|
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
|
-
*
|
|
575
|
+
* Property names are projected according to `TMapping` (see {@link FieldMapping}).
|
|
522
576
|
*
|
|
523
|
-
*
|
|
524
|
-
*
|
|
525
|
-
*
|
|
526
|
-
*
|
|
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
|
-
*
|
|
531
|
-
* (resolve.resolver, onSubmit, onChange, …)
|
|
584
|
+
* Non-reactive context — arbitrary data available in all callbacks
|
|
585
|
+
* (resolve.resolver, onSubmit, onChange, …) via `store.context`.
|
|
532
586
|
*
|
|
533
|
-
*
|
|
534
|
-
*
|
|
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
|
-
*
|
|
542
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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 —
|
|
634
|
+
* @param t — translation function, or null to clear
|
|
581
635
|
*/
|
|
582
636
|
setTranslator: (t: TranslateFn | null) => void;
|
|
583
637
|
/**
|
|
584
|
-
*
|
|
638
|
+
* Persistence manager — hydration and auto-saving of form state.
|
|
585
639
|
*/
|
|
586
640
|
persist: PersistManager;
|
|
587
641
|
/**
|
|
588
|
-
*
|
|
642
|
+
* Registers a notification function (toast, alert, …) for resolver onError.
|
|
589
643
|
*
|
|
590
|
-
* @param fn —
|
|
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
|
-
*
|
|
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
|
|
604
|
-
*
|
|
605
|
-
*
|
|
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
|
-
*
|
|
610
|
-
* -
|
|
611
|
-
* -
|
|
612
|
-
* - Batch
|
|
663
|
+
* Creates or updates an entity (or an array of entities) in the registry.
|
|
664
|
+
* - If no entity with the id exists — it 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
|
-
*
|
|
617
|
-
*
|
|
618
|
-
* No-op
|
|
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
|
}
|