palistor 0.0.25 → 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 +16 -27
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -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 +54 -53
- 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.js +39 -39
- package/dist/store/buildProxy/buildProxy.js.map +1 -1
- package/dist/store/buildProxy/computeProxyKeys.d.ts +8 -8
- package/dist/store/buildProxy/computeProxyKeys.js +9 -9
- 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 +48 -48
- package/dist/store/constants.d.ts.map +1 -1
- package/dist/store/constants.js +45 -45
- 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 +9 -9
- package/dist/store/flow/buildFlowStepsProxy.js +13 -13
- package/dist/store/flow/buildFlowStepsProxy.js.map +1 -1
- package/dist/store/flow/defineFlow.d.ts +27 -25
- package/dist/store/flow/defineFlow.d.ts.map +1 -1
- package/dist/store/flow/defineFlow.js +15 -13
- package/dist/store/flow/defineFlow.js.map +1 -1
- package/dist/store/flow/flowApi.d.ts +3 -2
- package/dist/store/flow/flowApi.d.ts.map +1 -1
- package/dist/store/flow/flowApi.js +1 -1
- package/dist/store/flow/flowApi.js.map +1 -1
- package/dist/store/flow/flowNavigation.d.ts +65 -63
- package/dist/store/flow/flowNavigation.d.ts.map +1 -1
- package/dist/store/flow/flowNavigation.js +74 -72
- package/dist/store/flow/flowNavigation.js.map +1 -1
- package/dist/store/flow/flowState.d.ts +16 -16
- package/dist/store/flow/flowState.d.ts.map +1 -1
- package/dist/store/flow/flowState.js +5 -5
- package/dist/store/flow/flowState.js.map +1 -1
- 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 +51 -51
- 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.js +15 -15
- 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 +61 -61
- package/dist/store/store/NodeRegistry/nodeRegistry.d.ts.map +1 -1
- package/dist/store/store/NodeRegistry/nodeRegistry.js +85 -86
- 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 +35 -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 +149 -169
- package/dist/store/store/palistor.js.map +1 -1
- package/dist/store/store/registerNodes.d.ts +10 -10
- package/dist/store/store/registerNodes.js +15 -15
- 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 +236 -234
- 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.js +12 -12
- 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
|
@@ -3,60 +3,60 @@ import type { EntityNode } from "../entityRegistry/types";
|
|
|
3
3
|
import type { MappableKey, MappableConfigKey } from "../constants";
|
|
4
4
|
import type { AnyFlowStep, FlowError, FlowStep, FlowValues, InferFlowSteps, StepStatus } from "../flow/defineFlow";
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
6
|
+
* Internal type for recursively walking the config tree.
|
|
7
|
+
* Used by registerNodes, buildProxy, applyPatch, recomputeAll, etc.
|
|
8
8
|
*/
|
|
9
9
|
export interface AnyConfigNode {
|
|
10
10
|
[key: string]: AnyConfigNode | unknown;
|
|
11
11
|
}
|
|
12
12
|
/**
|
|
13
|
-
*
|
|
14
|
-
* label/placeholder/description
|
|
15
|
-
*
|
|
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.
|
|
16
16
|
*/
|
|
17
17
|
export type TranslateFn = (...args: any[]) => string;
|
|
18
18
|
/**
|
|
19
|
-
*
|
|
19
|
+
* Form config type: an object where every key is a config node typed over TValues.
|
|
20
20
|
*/
|
|
21
21
|
export type FormConfig<TValues = Record<string, unknown>> = Record<string, ConfigNode<any, TValues>>;
|
|
22
22
|
import type { NotifyFn, Resolve } from "../resolvePipeline";
|
|
23
23
|
import type { SubmitResult } from "../submitPipeline/submitPipeline";
|
|
24
|
-
/**
|
|
24
|
+
/** Unsubscribe function returned by subscriptions. */
|
|
25
25
|
export type Unsubscribe = () => void;
|
|
26
26
|
/**
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
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.
|
|
30
30
|
*
|
|
31
31
|
* @example
|
|
32
|
-
* //
|
|
32
|
+
* // static
|
|
33
33
|
* isVisible: true
|
|
34
|
-
* //
|
|
34
|
+
* // computed
|
|
35
35
|
* isVisible: (values) => values.paymentType === "bank"
|
|
36
36
|
*/
|
|
37
37
|
export type MaybeComputed<TResult, TValues = Record<string, unknown>> = TResult | ((values: TValues) => TResult);
|
|
38
38
|
/**
|
|
39
|
-
*
|
|
40
|
-
* -
|
|
41
|
-
* - `(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
|
|
42
42
|
*/
|
|
43
43
|
export type MaybeTranslatable<TResult, TValues = Record<string, unknown>> = TResult | ((t: TranslateFn, values: TValues) => TResult);
|
|
44
44
|
/**
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
45
|
+
* Deeply optional version of the values.
|
|
46
|
+
* Recurses only into "plain" objects; arrays, Date, Map, Set, etc.
|
|
47
|
+
* are left as-is.
|
|
48
48
|
*/
|
|
49
49
|
export type DeepPartialValues<T> = {
|
|
50
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];
|
|
51
51
|
};
|
|
52
52
|
/**
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
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.
|
|
56
56
|
*/
|
|
57
57
|
type ProxyValueType<T> = T extends number ? T | string : T extends boolean ? T | string | number : T;
|
|
58
58
|
/**
|
|
59
|
-
*
|
|
59
|
+
* Field type metadata (for future type-based validation / codegen).
|
|
60
60
|
*/
|
|
61
61
|
export interface FieldTypeMeta {
|
|
62
62
|
readonly dataType: "String" | "Number" | "Boolean" | "Date" | "Array" | "Object";
|
|
@@ -64,17 +64,17 @@ export interface FieldTypeMeta {
|
|
|
64
64
|
}
|
|
65
65
|
export type { Setter } from "../writePipeline/writePipeline";
|
|
66
66
|
/**
|
|
67
|
-
*
|
|
67
|
+
* Universal config node — describes both a field and a group.
|
|
68
68
|
*
|
|
69
|
-
*
|
|
70
|
-
* -
|
|
71
|
-
* -
|
|
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)
|
|
72
72
|
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
73
|
+
* All properties except `value` are optional.
|
|
74
|
+
* Any computed property can be a constant or a function of `TValues`.
|
|
75
75
|
*
|
|
76
|
-
* @template TValue —
|
|
77
|
-
* @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>)
|
|
78
78
|
*/
|
|
79
79
|
export interface ConfigNode<TValue = unknown, TValues = Record<string, unknown>> {
|
|
80
80
|
value?: MaybeComputed<TValue, TValues>;
|
|
@@ -82,41 +82,41 @@ export interface ConfigNode<TValue = unknown, TValues = Record<string, unknown>>
|
|
|
82
82
|
placeholder?: MaybeTranslatable<string, TValues>;
|
|
83
83
|
description?: MaybeTranslatable<string, TValues>;
|
|
84
84
|
/**
|
|
85
|
-
*
|
|
86
|
-
* `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.
|
|
87
87
|
*/
|
|
88
88
|
validate?: (value: TValue, values: TValues, t: TranslateFn) => string | undefined | false;
|
|
89
|
-
/**
|
|
89
|
+
/** Transforms the input value before storing it (e.g. trims whitespace). */
|
|
90
90
|
formatter?: (value: string | boolean, values: TValues) => string | number | boolean;
|
|
91
|
-
/**
|
|
91
|
+
/** Write side-effect: returns a patch for other fields. */
|
|
92
92
|
setter?: (value: TValue, values: TValues, previousValue: TValue | undefined) => DeepPartialValues<TValues>;
|
|
93
|
-
/**
|
|
93
|
+
/** Extra props for the UI component. */
|
|
94
94
|
componentProps?: Readonly<Record<string, unknown>>;
|
|
95
|
-
/**
|
|
95
|
+
/** Field names whose changes trigger a recompute of this field's state. */
|
|
96
96
|
dependencies?: readonly string[];
|
|
97
|
-
/**
|
|
97
|
+
/** Field type metadata. */
|
|
98
98
|
types?: FieldTypeMeta;
|
|
99
99
|
isRequired?: MaybeComputed<boolean, TValues>;
|
|
100
100
|
isReadOnly?: MaybeComputed<boolean, TValues>;
|
|
101
101
|
isDisabled?: MaybeComputed<boolean, TValues>;
|
|
102
102
|
isVisible?: MaybeComputed<boolean, TValues>;
|
|
103
103
|
/**
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
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`
|
|
107
107
|
*/
|
|
108
108
|
beforeSubmit?: ((value: TValue, values: TValues) => TValue) | ((values: TValues) => TValues);
|
|
109
|
-
/**
|
|
109
|
+
/** Form submit callback. Invoked after validation in the submit pipeline. */
|
|
110
110
|
onSubmit?: (value: TValue | TValues, store: ProxyStore<any>, parent?: any) => Promise<unknown> | unknown;
|
|
111
|
-
/**
|
|
111
|
+
/** Post-processing after a successful onSubmit. */
|
|
112
112
|
afterSubmit?: (result: unknown, actions: {
|
|
113
113
|
reset: () => void;
|
|
114
114
|
}) => void | Promise<void>;
|
|
115
|
-
/**
|
|
115
|
+
/** Reset transformer: receives defaults, returns the final values. */
|
|
116
116
|
reset?: (defaults: TValues) => TValues;
|
|
117
117
|
/**
|
|
118
|
-
*
|
|
119
|
-
*
|
|
118
|
+
* Called after any field in the group changes (fire-and-forget).
|
|
119
|
+
* May return a patch to merge back into the store.
|
|
120
120
|
*/
|
|
121
121
|
onChange?: (info: {
|
|
122
122
|
fieldKey: string;
|
|
@@ -133,16 +133,15 @@ export interface ConfigNode<TValue = unknown, TValues = Record<string, unknown>>
|
|
|
133
133
|
resolve?: Resolve<TValue>;
|
|
134
134
|
}
|
|
135
135
|
/**
|
|
136
|
-
*
|
|
137
|
-
* группового узла).
|
|
136
|
+
* Config keys that are not child fields (hidden when mapping over a group node).
|
|
138
137
|
*/
|
|
139
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";
|
|
140
139
|
/**
|
|
141
|
-
*
|
|
142
|
-
*
|
|
140
|
+
* Shape of a leaf field as seen through the proxy.
|
|
141
|
+
* All functions (isVisible, validate, …) are already evaluated.
|
|
143
142
|
*/
|
|
144
143
|
export interface FieldProxyNode<TValue = unknown> {
|
|
145
|
-
/**
|
|
144
|
+
/** Reads return the typed value; writes accept a widened type (string for number fields, etc.). */
|
|
146
145
|
get value(): TValue;
|
|
147
146
|
set value(v: ProxyValueType<TValue>);
|
|
148
147
|
readonly label: string | undefined;
|
|
@@ -152,26 +151,26 @@ export interface FieldProxyNode<TValue = unknown> {
|
|
|
152
151
|
readonly isReadOnly: boolean;
|
|
153
152
|
readonly isDisabled: boolean;
|
|
154
153
|
readonly isVisible: boolean;
|
|
155
|
-
/** true
|
|
154
|
+
/** true when the field has a validation error. */
|
|
156
155
|
readonly isInvalid: boolean | undefined;
|
|
157
156
|
readonly errorMessage: string | undefined;
|
|
158
|
-
/** true
|
|
157
|
+
/** true when the current value differs from the initial one. */
|
|
159
158
|
readonly dirty: boolean;
|
|
160
159
|
readonly onValueChange: (v: ProxyValueType<TValue>) => void;
|
|
161
|
-
/** true
|
|
160
|
+
/** true while the submit pipeline is running (same as GroupProxyNode). */
|
|
162
161
|
readonly submitting: boolean;
|
|
163
162
|
/** Submit pipeline: submitting → beforeSubmit → validate → onSubmit → afterSubmit. */
|
|
164
163
|
submit(): Promise<SubmitResult>;
|
|
165
164
|
}
|
|
166
|
-
/**
|
|
165
|
+
/** Extracts the value type from a config node. */
|
|
167
166
|
type ExtractNodeValue<T> = T extends {
|
|
168
167
|
value: (...args: any[]) => infer R;
|
|
169
168
|
} ? R : T extends {
|
|
170
169
|
value: infer V;
|
|
171
170
|
} ? V : never;
|
|
172
171
|
/**
|
|
173
|
-
*
|
|
174
|
-
*
|
|
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).
|
|
175
174
|
*/
|
|
176
175
|
export interface GroupProxyNode {
|
|
177
176
|
readonly isVisible: boolean;
|
|
@@ -180,34 +179,34 @@ export interface GroupProxyNode {
|
|
|
180
179
|
readonly isDisabled: boolean | undefined;
|
|
181
180
|
readonly isInvalid: boolean | undefined;
|
|
182
181
|
readonly errorMessage: string | undefined;
|
|
183
|
-
/** true
|
|
182
|
+
/** true while the submit pipeline is running. */
|
|
184
183
|
readonly submitting: boolean;
|
|
185
184
|
/** true while async resolver is loading (only for nodes with resolve). */
|
|
186
185
|
readonly loading: boolean;
|
|
187
|
-
/** true
|
|
186
|
+
/** true when at least one field in the group differs from its initial value. */
|
|
188
187
|
readonly dirty: boolean;
|
|
189
188
|
/**
|
|
190
|
-
* true
|
|
191
|
-
* false
|
|
189
|
+
* true after the first failed submit — errors are shown in real time.
|
|
190
|
+
* false before the first submit — errors are hidden.
|
|
192
191
|
*/
|
|
193
192
|
readonly revalidate: boolean;
|
|
194
|
-
/**
|
|
193
|
+
/** Current values of all leaf fields in the subtree as a nested object. Live reference (not a clone). */
|
|
195
194
|
readonly values: Record<string, unknown>;
|
|
196
195
|
/** Submit pipeline: submitting → beforeSubmit → validate → onSubmit → afterSubmit. */
|
|
197
196
|
submit(): Promise<SubmitResult>;
|
|
198
|
-
/**
|
|
197
|
+
/** Resets the subtree to config defaults (or to the provided values). */
|
|
199
198
|
reset(values?: Record<string, unknown>): void;
|
|
200
199
|
/**
|
|
201
|
-
* Bulk
|
|
202
|
-
*
|
|
203
|
-
*
|
|
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.
|
|
204
203
|
*/
|
|
205
204
|
setValues(patch: Record<string, unknown>): void;
|
|
206
205
|
}
|
|
207
206
|
/**
|
|
208
|
-
*
|
|
209
|
-
*
|
|
210
|
-
* (
|
|
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).
|
|
211
210
|
*/
|
|
212
211
|
export interface ListResolveConfig {
|
|
213
212
|
/** Async data loader — returns array of entity records. */
|
|
@@ -229,45 +228,45 @@ export interface ListResolveConfig {
|
|
|
229
228
|
};
|
|
230
229
|
}
|
|
231
230
|
/**
|
|
232
|
-
*
|
|
233
|
-
*
|
|
231
|
+
* List-level configuration (second element of a ListNode array).
|
|
232
|
+
* The resolver and other list-level options go here.
|
|
234
233
|
*/
|
|
235
234
|
export interface ListConfig {
|
|
236
235
|
resolve?: ListResolveConfig;
|
|
237
236
|
}
|
|
238
237
|
/**
|
|
239
|
-
*
|
|
238
|
+
* Internal list state — the SINGLE "list" building block (root + per-entity).
|
|
240
239
|
*
|
|
241
|
-
*
|
|
242
|
-
*
|
|
243
|
-
* 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.
|
|
244
243
|
*
|
|
245
|
-
* Root
|
|
246
|
-
* per-entity
|
|
244
|
+
* Root `ListState` lives in `NodeRegistry.listStates` (keyed by `listConfigNode`),
|
|
245
|
+
* per-entity ones live in `owner.lists` (same `listConfigNode` key).
|
|
247
246
|
*/
|
|
248
247
|
export interface ListState {
|
|
249
|
-
/**
|
|
248
|
+
/** The array config node [template, listConfig?] — key in all registries. */
|
|
250
249
|
listConfigNode: object;
|
|
251
|
-
/**
|
|
250
|
+
/** Item template — describes the fields to render. listConfigNode[0]. */
|
|
252
251
|
template: object;
|
|
253
|
-
/**
|
|
252
|
+
/** List configuration (resolve etc.). listConfigNode[1] — optional. */
|
|
254
253
|
listConfig?: ListConfig;
|
|
255
|
-
/**
|
|
254
|
+
/** List owner. `null` = root list; otherwise the owning entity. */
|
|
256
255
|
ownerEntity: EntityNode | null;
|
|
257
|
-
/**
|
|
256
|
+
/** IDs of the entities in the list (in display order). */
|
|
258
257
|
itemIds: string[];
|
|
259
|
-
/**
|
|
258
|
+
/** Captured at init/resolve — used for membership dirty-tracking. */
|
|
260
259
|
initialItemIds: string[];
|
|
261
260
|
}
|
|
262
261
|
/**
|
|
263
|
-
*
|
|
264
|
-
* TItem —
|
|
262
|
+
* Proxy interface for a list (ListNode in the config).
|
|
263
|
+
* TItem — type of a single item (EntityProjectionProxy).
|
|
265
264
|
*/
|
|
266
265
|
export interface ListProxyNode<TItem> {
|
|
267
266
|
readonly items: ReadonlyArray<TItem>;
|
|
268
267
|
readonly length: number;
|
|
269
268
|
readonly loading: boolean;
|
|
270
|
-
/** true
|
|
269
|
+
/** true when list membership changed since init/last resolve. */
|
|
271
270
|
readonly dirty: boolean;
|
|
272
271
|
add(id: string): void;
|
|
273
272
|
add(values: Record<string, unknown>): TItem;
|
|
@@ -280,77 +279,77 @@ export interface ListProxyNode<TItem> {
|
|
|
280
279
|
}
|
|
281
280
|
declare const __palistorRefBrand: unique symbol;
|
|
282
281
|
declare const __typedListBrand: unique symbol;
|
|
283
|
-
/** Opaque
|
|
282
|
+
/** Opaque reference to an entity proxy. Passed as a prop, unwrapped via useForm(). */
|
|
284
283
|
export type PalistorRef<T extends Record<string, any>> = {
|
|
285
284
|
readonly [__palistorRefBrand]: T;
|
|
286
285
|
} & object;
|
|
287
|
-
/**
|
|
286
|
+
/** Typed entity list. */
|
|
288
287
|
export type PalistorList<T extends Record<string, any>> = ListProxyNode<PalistorRef<T>>;
|
|
289
|
-
/**
|
|
288
|
+
/** Marker type for a typed list node in the config. */
|
|
290
289
|
export type TypedListNode<TEntity extends Record<string, any>> = readonly [any, any?] & {
|
|
291
290
|
readonly [__typedListBrand]: TEntity;
|
|
292
291
|
};
|
|
293
|
-
/** Typed resolver
|
|
292
|
+
/** Typed list resolver. */
|
|
294
293
|
export type ListResolver<TEntity extends Record<string, any>> = (values: any, store: ProxyStore<any>) => Promise<TEntity[]>;
|
|
295
|
-
/** Typed template:
|
|
294
|
+
/** Typed template: each Entity key → ConfigNode with the matching value type. */
|
|
296
295
|
export type TemplateConfig<TEntity extends Record<string, any>> = {
|
|
297
296
|
[K in keyof TEntity]: ConfigNode<TEntity[K], TEntity>;
|
|
298
297
|
};
|
|
299
|
-
/**
|
|
298
|
+
/** Extract the entity type from a PalistorRef. */
|
|
300
299
|
export type InferEntity<T> = T extends PalistorRef<infer E> ? E : never;
|
|
301
300
|
/**
|
|
302
|
-
*
|
|
303
|
-
*
|
|
301
|
+
* Proxy of a single flow step: the step config's regular group proxy,
|
|
302
|
+
* enriched with the computed `status` (see {@link StepStatus}).
|
|
304
303
|
*/
|
|
305
304
|
export type FlowStepProxy<C, M extends FieldMapping = {}> = ConfigNodeToProxy<C, M> & {
|
|
306
305
|
readonly status: StepStatus;
|
|
307
306
|
};
|
|
308
307
|
/**
|
|
309
|
-
*
|
|
310
|
-
*
|
|
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.
|
|
311
310
|
*/
|
|
312
311
|
export type FlowStepsProxy<S extends readonly AnyFlowStep[], M extends FieldMapping = {}> = {
|
|
313
312
|
readonly [I in keyof S]: S[I] extends FlowStep<any, infer C> ? FlowStepProxy<C, M> : never;
|
|
314
313
|
} & {
|
|
315
314
|
readonly [Step in S[number] as Step["key"]]: FlowStepProxy<Step["config"], M>;
|
|
316
315
|
} & {
|
|
317
|
-
/**
|
|
316
|
+
/** Proxy of the active step — replaced on every navigation. */
|
|
318
317
|
readonly current: FlowStepProxy<S[number]["config"], M>;
|
|
319
318
|
};
|
|
320
319
|
/**
|
|
321
|
-
*
|
|
320
|
+
* Proxy of a flow node (defineFlow): group proxy + navigation state and methods.
|
|
322
321
|
*/
|
|
323
322
|
export type FlowProxyNode<S extends readonly AnyFlowStep[], M extends FieldMapping = {}> = Omit<ApplyFieldMapping<GroupProxyNode, M>, "values"> & {
|
|
324
|
-
/**
|
|
323
|
+
/** Key of the active step (reactive). */
|
|
325
324
|
readonly currentStepKey: S[number]["key"];
|
|
326
|
-
/**
|
|
325
|
+
/** Index of the active step (reactive). */
|
|
327
326
|
readonly currentStepIndex: number;
|
|
328
|
-
/** true
|
|
327
|
+
/** true when the visit stack is non-empty (reliable guard for a Back button). */
|
|
329
328
|
readonly canGoBack: boolean;
|
|
330
|
-
/**
|
|
329
|
+
/** Visit path: [...visitStack, currentStepKey] (reactive). */
|
|
331
330
|
readonly history: readonly string[];
|
|
332
|
-
/**
|
|
331
|
+
/** Errors from the last validate()/finalization (reactive). */
|
|
333
332
|
readonly errors: ReadonlyArray<FlowError>;
|
|
334
|
-
/**
|
|
333
|
+
/** Step collection: steps[0], steps.key, steps.current, steps.length. */
|
|
335
334
|
readonly steps: FlowStepsProxy<S, M>;
|
|
336
|
-
/**
|
|
335
|
+
/** Accumulated values of all steps — live reference (like a group's). */
|
|
337
336
|
readonly values: FlowValues<S>;
|
|
338
|
-
/**
|
|
337
|
+
/** Advance to the next VISIBLE step; if none remain — finalize via submit(). */
|
|
339
338
|
nextStep(): void;
|
|
340
|
-
/**
|
|
339
|
+
/** Go back along the visit stack. No-op when the stack is empty. */
|
|
341
340
|
back(): void;
|
|
342
|
-
/**
|
|
341
|
+
/** Jump to a step by key or index. Throws on an unknown key/index. */
|
|
343
342
|
goTo(keyOrIndex: S[number]["key"] | number): void;
|
|
344
|
-
/**
|
|
343
|
+
/** Validate visited steps → errors land in flow.errors. Empty array = valid. */
|
|
345
344
|
validate(): FlowError[];
|
|
346
345
|
};
|
|
347
346
|
/**
|
|
348
|
-
*
|
|
347
|
+
* Recursively converts a config node into its proxy type:
|
|
349
348
|
* - FlowNode (defineFlow) → `FlowProxyNode<S>`
|
|
350
349
|
* - TypedListNode (defineList<TEntity>) → `ListProxyNode<PalistorRef<TEntity>>`
|
|
351
|
-
* - ListNode (
|
|
352
|
-
* -
|
|
353
|
-
* -
|
|
350
|
+
* - ListNode (array `[template, listConfig?]`) → `ListProxyNode<...>`
|
|
351
|
+
* - Leaf node (has `value`) → `FieldProxyNode<TValue>`
|
|
352
|
+
* - Group node → `GroupProxyNode & { child fields… }`
|
|
354
353
|
*/
|
|
355
354
|
type ConfigNodeToProxy<T, M extends FieldMapping = {}> = [
|
|
356
355
|
InferFlowSteps<T>
|
|
@@ -362,28 +361,28 @@ type ConfigNodeToProxy<T, M extends FieldMapping = {}> = [
|
|
|
362
361
|
[K in keyof T as K extends ConfigSkipKeys ? never : K]: ConfigNodeToProxy<T[K], M>;
|
|
363
362
|
} : never : FlowProxyNode<InferFlowSteps<T>, M>;
|
|
364
363
|
/**
|
|
365
|
-
*
|
|
366
|
-
*
|
|
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, …).
|
|
367
366
|
*
|
|
368
|
-
* `M`
|
|
369
|
-
* (identity:
|
|
367
|
+
* `M` is the field rename map (see {@link FieldMapping}). Defaults to `{}`
|
|
368
|
+
* (identity: property names are unchanged).
|
|
370
369
|
*/
|
|
371
370
|
export type ConfigProxy<TConfig extends Record<string, any>, M extends FieldMapping = {}> = ApplyFieldMapping<GroupProxyNode, M> & {
|
|
372
371
|
[K in keyof TConfig]: ConfigNodeToProxy<TConfig[K], M>;
|
|
373
372
|
};
|
|
374
373
|
declare const __rawStoreBrand: unique symbol;
|
|
375
374
|
/**
|
|
376
|
-
*
|
|
377
|
-
* `useForm()` —
|
|
378
|
-
*
|
|
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.
|
|
379
378
|
*/
|
|
380
379
|
export interface RawStoreProxyMarker {
|
|
381
380
|
readonly [__rawStoreBrand]: "Do not pass store.proxy or store.proxy.subtree to useForm. Use: const form = useForm(store); then form.subtree";
|
|
382
381
|
}
|
|
383
382
|
/**
|
|
384
|
-
*
|
|
385
|
-
*
|
|
386
|
-
*
|
|
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.
|
|
387
386
|
*/
|
|
388
387
|
type ConfigNodeToProxyRaw<T, M extends FieldMapping = {}> = [
|
|
389
388
|
InferFlowSteps<T>
|
|
@@ -395,12 +394,11 @@ type ConfigNodeToProxyRaw<T, M extends FieldMapping = {}> = [
|
|
|
395
394
|
[K in keyof T as K extends ConfigSkipKeys ? never : K]: ConfigNodeToProxyRaw<T[K], M>;
|
|
396
395
|
} : never : FlowProxyNode<InferFlowSteps<T>, M> & RawStoreProxyMarker;
|
|
397
396
|
/**
|
|
398
|
-
*
|
|
399
|
-
*
|
|
400
|
-
*
|
|
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)`.
|
|
401
400
|
*
|
|
402
|
-
*
|
|
403
|
-
* ошибке вида:
|
|
401
|
+
* Passing such a value (or its subtree) into `useForm` produces an error like:
|
|
404
402
|
* Argument of type 'X' is not assignable to parameter of type
|
|
405
403
|
* '_PALISTOR_ERROR__do_not_pass_store_proxy_subtree_to_useForm__call_useForm_store_first'.
|
|
406
404
|
*/
|
|
@@ -408,8 +406,8 @@ export type RawStoreProxy<TConfig extends Record<string, any>, M extends FieldMa
|
|
|
408
406
|
[K in keyof TConfig]: ConfigNodeToProxyRaw<TConfig[K], M>;
|
|
409
407
|
};
|
|
410
408
|
/**
|
|
411
|
-
*
|
|
412
|
-
*
|
|
409
|
+
* Proxy for a single entity: id is exposed as string,
|
|
410
|
+
* remaining fields follow the Palistor<T> rules.
|
|
413
411
|
*/
|
|
414
412
|
export type PalistorEntityProxy<T extends {
|
|
415
413
|
id?: any;
|
|
@@ -419,14 +417,14 @@ export type PalistorEntityProxy<T extends {
|
|
|
419
417
|
[K in Exclude<keyof T, "id">]: T[K] extends Record<string, any> ? Palistor<T[K]> : FieldProxyNode<T[K]>;
|
|
420
418
|
};
|
|
421
419
|
/**
|
|
422
|
-
*
|
|
423
|
-
*
|
|
424
|
-
*
|
|
425
|
-
*
|
|
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.
|
|
426
424
|
*
|
|
427
|
-
*
|
|
428
|
-
*
|
|
429
|
-
*
|
|
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"`.
|
|
430
428
|
*
|
|
431
429
|
* @example
|
|
432
430
|
* ```ts
|
|
@@ -444,10 +442,10 @@ export type Palistor<T extends Record<string, any> = {}, M extends FieldMapping
|
|
|
444
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>;
|
|
445
443
|
};
|
|
446
444
|
/**
|
|
447
|
-
*
|
|
448
|
-
*
|
|
449
|
-
*
|
|
450
|
-
*
|
|
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.
|
|
451
449
|
*/
|
|
452
450
|
export type ExtractValues<T> = {
|
|
453
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 {
|
|
@@ -455,15 +453,15 @@ export type ExtractValues<T> = {
|
|
|
455
453
|
} ? ExtractNodeValue<T[K]> : T[K] extends Record<string, any> ? ExtractValues<T[K]> : never : FlowValues<InferFlowSteps<T[K]>>;
|
|
456
454
|
};
|
|
457
455
|
/**
|
|
458
|
-
*
|
|
456
|
+
* internal → external rename map for projecting field names through the proxy.
|
|
459
457
|
*
|
|
460
|
-
* Sparse:
|
|
461
|
-
*
|
|
462
|
-
*
|
|
463
|
-
* 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.
|
|
464
461
|
*
|
|
465
|
-
*
|
|
466
|
-
*
|
|
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.
|
|
467
465
|
*
|
|
468
466
|
* @example
|
|
469
467
|
* fieldMapping: {
|
|
@@ -474,85 +472,89 @@ export type ExtractValues<T> = {
|
|
|
474
472
|
*/
|
|
475
473
|
export type FieldMapping = Partial<Record<MappableKey, string>>;
|
|
476
474
|
/**
|
|
477
|
-
*
|
|
478
|
-
*
|
|
479
|
-
*
|
|
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.
|
|
480
478
|
*
|
|
481
|
-
*
|
|
482
|
-
*
|
|
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).
|
|
483
482
|
*/
|
|
484
483
|
export type ApplyFieldMapping<T, M extends FieldMapping> = keyof M extends never ? T : {
|
|
485
484
|
[K in keyof T as K extends keyof M ? (M[K] extends string ? M[K] : K) : K]: T[K];
|
|
486
485
|
};
|
|
487
486
|
declare const CONFIG_KEY_ERROR: unique symbol;
|
|
488
|
-
/**
|
|
489
|
-
*
|
|
487
|
+
/** Branded error type: makes the property unassignable and surfaces the hint
|
|
488
|
+
* text in the compiler message. */
|
|
490
489
|
export type ConfigKeyError<Msg extends string> = {
|
|
491
490
|
readonly [CONFIG_KEY_ERROR]: Msg;
|
|
492
491
|
};
|
|
493
|
-
/** Internal
|
|
492
|
+
/** Internal config key names actively renamed by the map `M`. */
|
|
494
493
|
type RemappedInternalConfigKey<M extends FieldMapping> = keyof M & MappableConfigKey;
|
|
495
494
|
/**
|
|
496
|
-
*
|
|
497
|
-
* INTERNAL
|
|
498
|
-
*
|
|
499
|
-
*
|
|
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).
|
|
500
499
|
*
|
|
501
|
-
*
|
|
502
|
-
*
|
|
500
|
+
* Intersected with `TConfig` in the `config` option, so valid keys keep their
|
|
501
|
+
* original type (`T[K] & unknown`) while offending ones become unassignable.
|
|
503
502
|
*/
|
|
504
503
|
export type ValidateExternalConfig<T, M extends FieldMapping> = keyof M extends never ? unknown : T extends object ? {
|
|
505
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>;
|
|
506
505
|
} : unknown;
|
|
507
506
|
/**
|
|
508
|
-
*
|
|
509
|
-
*
|
|
510
|
-
*
|
|
511
|
-
*
|
|
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.
|
|
512
512
|
*/
|
|
513
513
|
export type ExternalConfigNode<M extends FieldMapping, TValue = unknown, TValues = Record<string, unknown>> = ApplyFieldMapping<ConfigNode<TValue, TValues>, M>;
|
|
514
514
|
/**
|
|
515
|
-
*
|
|
516
|
-
*
|
|
517
|
-
* 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.
|
|
518
518
|
*
|
|
519
|
-
* ⚠️
|
|
520
|
-
*
|
|
521
|
-
*
|
|
522
|
-
* `config` (
|
|
523
|
-
*
|
|
524
|
-
*
|
|
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.
|
|
525
526
|
*/
|
|
526
527
|
export type ExternalConfig<M extends FieldMapping, TValues = Record<string, unknown>> = Record<string, ExternalConfigNode<M, any, TValues>>;
|
|
527
528
|
export interface ProxyStoreOptions<TConfig extends Record<string, any>, TMapping extends FieldMapping = {}> {
|
|
528
529
|
/**
|
|
529
|
-
*
|
|
530
|
+
* Declarative description of the form structure and fields. Never mutated.
|
|
530
531
|
*
|
|
531
|
-
*
|
|
532
|
-
* (external
|
|
533
|
-
* {@link ValidateExternalConfig}
|
|
534
|
-
*
|
|
535
|
-
*
|
|
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.
|
|
536
538
|
*/
|
|
537
539
|
config: TConfig & ValidateExternalConfig<TConfig, NoInfer<TMapping>>;
|
|
538
540
|
/**
|
|
539
|
-
*
|
|
540
|
-
*
|
|
541
|
+
* Initial values that override the defaults from the config.
|
|
542
|
+
* Mirrors the config structure, but all fields are optional.
|
|
541
543
|
*/
|
|
542
544
|
initialValues?: DeepPartialValues<ExtractValues<TConfig>>;
|
|
543
545
|
/**
|
|
544
|
-
*
|
|
545
|
-
*
|
|
546
|
+
* Initial context. When provided, eager resolvers see it on their first run.
|
|
547
|
+
* Equivalent to calling `setContext()` before `launchEager()`.
|
|
546
548
|
*/
|
|
547
549
|
context?: Record<string, unknown>;
|
|
548
550
|
/**
|
|
549
|
-
*
|
|
550
|
-
*
|
|
551
|
-
* 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.
|
|
552
554
|
*
|
|
553
|
-
*
|
|
554
|
-
*
|
|
555
|
-
*
|
|
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`.
|
|
556
558
|
*
|
|
557
559
|
* @see FieldMapping
|
|
558
560
|
*/
|
|
@@ -560,86 +562,86 @@ export interface ProxyStoreOptions<TConfig extends Record<string, any>, TMapping
|
|
|
560
562
|
}
|
|
561
563
|
export interface ProxyStore<TConfig extends Record<string, any>, TMapping extends FieldMapping = {}> {
|
|
562
564
|
/**
|
|
563
|
-
* @internal
|
|
564
|
-
*
|
|
565
|
-
*
|
|
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.
|
|
566
568
|
*/
|
|
567
569
|
readonly externalToInternal: Record<string, string>;
|
|
568
570
|
/**
|
|
569
|
-
*
|
|
570
|
-
* GET .value / .isVisible / … →
|
|
571
|
+
* Reactive proxy. Mirrors the config structure.
|
|
572
|
+
* GET .value / .isVisible / … → from the computed FieldState
|
|
571
573
|
* SET .value = X → formatter → validate → recompute → notify
|
|
572
574
|
*
|
|
573
|
-
*
|
|
575
|
+
* Property names are projected according to `TMapping` (see {@link FieldMapping}).
|
|
574
576
|
*
|
|
575
|
-
*
|
|
576
|
-
*
|
|
577
|
-
*
|
|
578
|
-
*
|
|
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.
|
|
579
581
|
*/
|
|
580
582
|
proxy: RawStoreProxy<TConfig, TMapping>;
|
|
581
583
|
/**
|
|
582
|
-
*
|
|
583
|
-
* (resolve.resolver, onSubmit, onChange, …)
|
|
584
|
+
* Non-reactive context — arbitrary data available in all callbacks
|
|
585
|
+
* (resolve.resolver, onSubmit, onChange, …) via `store.context`.
|
|
584
586
|
*
|
|
585
|
-
*
|
|
586
|
-
*
|
|
587
|
+
* Set via `setContext()` or the `useStoreContext()` hook.
|
|
588
|
+
* Not part of the form — excluded from getValues(), submit, persist.
|
|
587
589
|
*
|
|
588
590
|
* @example
|
|
589
591
|
* store.context.accountId; // read
|
|
590
592
|
*/
|
|
591
593
|
readonly context: Record<string, unknown>;
|
|
592
594
|
/**
|
|
593
|
-
*
|
|
594
|
-
*
|
|
595
|
+
* Sets the non-reactive context. Replaces the current context wholesale.
|
|
596
|
+
* Called from React (useStoreContext) or imperatively.
|
|
595
597
|
*
|
|
596
598
|
* @example
|
|
597
599
|
* store.setContext({ accountId: "abc", tenant: "acme" });
|
|
598
600
|
*/
|
|
599
601
|
setContext(ctx: Record<string, unknown>): void;
|
|
600
602
|
/**
|
|
601
|
-
*
|
|
602
|
-
*
|
|
603
|
+
* Subscribes to state changes of a specific config node.
|
|
604
|
+
* Returns an unsubscribe function.
|
|
603
605
|
*/
|
|
604
606
|
subscribe: (node: object, listener: () => void) => Unsubscribe;
|
|
605
607
|
/**
|
|
606
|
-
*
|
|
607
|
-
*
|
|
608
|
-
*
|
|
608
|
+
* Subscribes to ANY store change.
|
|
609
|
+
* Used by useForm for useSyncExternalStore.
|
|
610
|
+
* Returns an unsubscribe function.
|
|
609
611
|
*/
|
|
610
612
|
subscribeGlobal: (listener: () => void) => Unsubscribe;
|
|
611
613
|
/**
|
|
612
|
-
*
|
|
613
|
-
*
|
|
614
|
+
* Global store version. Incremented on every change.
|
|
615
|
+
* Used as the snapshot for useSyncExternalStore.
|
|
614
616
|
*/
|
|
615
617
|
getVersion: () => number;
|
|
616
618
|
/**
|
|
617
|
-
*
|
|
618
|
-
*
|
|
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).
|
|
619
621
|
*/
|
|
620
622
|
getNodeVersion: (node: object) => number;
|
|
621
623
|
/**
|
|
622
|
-
*
|
|
624
|
+
* All current field values as a nested object.
|
|
623
625
|
*/
|
|
624
626
|
getValues: () => ExtractValues<TConfig>;
|
|
625
627
|
/**
|
|
626
|
-
*
|
|
628
|
+
* Registers a translation function (next-intl, i18next, …) for resolving
|
|
627
629
|
* label / placeholder / description.
|
|
628
630
|
*
|
|
629
|
-
*
|
|
630
|
-
*
|
|
631
|
+
* When the translator changes, all subscribed components re-render with
|
|
632
|
+
* up-to-date translations.
|
|
631
633
|
*
|
|
632
|
-
* @param t —
|
|
634
|
+
* @param t — translation function, or null to clear
|
|
633
635
|
*/
|
|
634
636
|
setTranslator: (t: TranslateFn | null) => void;
|
|
635
637
|
/**
|
|
636
|
-
*
|
|
638
|
+
* Persistence manager — hydration and auto-saving of form state.
|
|
637
639
|
*/
|
|
638
640
|
persist: PersistManager;
|
|
639
641
|
/**
|
|
640
|
-
*
|
|
642
|
+
* Registers a notification function (toast, alert, …) for resolver onError.
|
|
641
643
|
*
|
|
642
|
-
* @param fn —
|
|
644
|
+
* @param fn — notification function, or null to clear
|
|
643
645
|
*/
|
|
644
646
|
setNotifier: (fn: NotifyFn | null) => void;
|
|
645
647
|
/**
|
|
@@ -648,26 +650,26 @@ export interface ProxyStore<TConfig extends Record<string, any>, TMapping extend
|
|
|
648
650
|
*/
|
|
649
651
|
submit(): Promise<SubmitResult>;
|
|
650
652
|
/**
|
|
651
|
-
*
|
|
653
|
+
* Resets the root form to config defaults (or to the provided values).
|
|
652
654
|
*/
|
|
653
655
|
reset(values?: DeepPartialValues<ExtractValues<TConfig>>): void;
|
|
654
656
|
/**
|
|
655
|
-
* Bulk
|
|
656
|
-
*
|
|
657
|
-
*
|
|
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.
|
|
658
660
|
*/
|
|
659
661
|
setValues(patch: DeepPartialValues<ExtractValues<TConfig>>): void;
|
|
660
662
|
/**
|
|
661
|
-
*
|
|
662
|
-
* -
|
|
663
|
-
* -
|
|
664
|
-
* - 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.
|
|
665
667
|
*/
|
|
666
668
|
set(data: import("../entityRegistry").EntityData | import("../entityRegistry").EntityData[]): void;
|
|
667
669
|
/**
|
|
668
|
-
*
|
|
669
|
-
*
|
|
670
|
-
* 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.
|
|
671
673
|
*/
|
|
672
674
|
delete(id: string): void;
|
|
673
675
|
}
|