palistor 0.0.24
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/LICENSE +21 -0
- package/README.md +947 -0
- package/dist/index.d.ts +54 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +58 -0
- package/dist/index.js.map +1 -0
- package/dist/react/createTrackingProxy.d.ts +55 -0
- package/dist/react/createTrackingProxy.d.ts.map +1 -0
- package/dist/react/createTrackingProxy.js +149 -0
- package/dist/react/createTrackingProxy.js.map +1 -0
- package/dist/react/useForm.d.ts +108 -0
- package/dist/react/useForm.d.ts.map +1 -0
- package/dist/react/useForm.js +180 -0
- package/dist/react/useForm.js.map +1 -0
- package/dist/react/useNotifier.d.ts +35 -0
- package/dist/react/useNotifier.d.ts.map +1 -0
- package/dist/react/useNotifier.js +41 -0
- package/dist/react/useNotifier.js.map +1 -0
- package/dist/react/usePersist.d.ts +45 -0
- package/dist/react/usePersist.d.ts.map +1 -0
- package/dist/react/usePersist.js +60 -0
- package/dist/react/usePersist.js.map +1 -0
- package/dist/react/useStoreContext.d.ts +42 -0
- package/dist/react/useStoreContext.d.ts.map +1 -0
- package/dist/react/useStoreContext.js +46 -0
- package/dist/react/useStoreContext.js.map +1 -0
- package/dist/react/useTranslator.d.ts +37 -0
- package/dist/react/useTranslator.d.ts.map +1 -0
- package/dist/react/useTranslator.js +43 -0
- package/dist/react/useTranslator.js.map +1 -0
- package/dist/store/applyPatch/applyPatch.d.ts +17 -0
- package/dist/store/applyPatch/applyPatch.d.ts.map +1 -0
- package/dist/store/applyPatch/applyPatch.js +44 -0
- package/dist/store/applyPatch/applyPatch.js.map +1 -0
- package/dist/store/buildProxy/buildEntityProjectionProxy.d.ts +52 -0
- package/dist/store/buildProxy/buildEntityProjectionProxy.d.ts.map +1 -0
- package/dist/store/buildProxy/buildEntityProjectionProxy.js +321 -0
- package/dist/store/buildProxy/buildEntityProjectionProxy.js.map +1 -0
- package/dist/store/buildProxy/buildListProxy.d.ts +33 -0
- package/dist/store/buildProxy/buildListProxy.d.ts.map +1 -0
- package/dist/store/buildProxy/buildListProxy.js +306 -0
- package/dist/store/buildProxy/buildListProxy.js.map +1 -0
- package/dist/store/buildProxy/buildProxy.d.ts +41 -0
- package/dist/store/buildProxy/buildProxy.d.ts.map +1 -0
- package/dist/store/buildProxy/buildProxy.js +380 -0
- package/dist/store/buildProxy/buildProxy.js.map +1 -0
- package/dist/store/buildProxy/computeProxyKeys.d.ts +15 -0
- package/dist/store/buildProxy/computeProxyKeys.d.ts.map +1 -0
- package/dist/store/buildProxy/computeProxyKeys.js +28 -0
- package/dist/store/buildProxy/computeProxyKeys.js.map +1 -0
- package/dist/store/buildProxy/handleLazyResolve.d.ts +10 -0
- package/dist/store/buildProxy/handleLazyResolve.d.ts.map +1 -0
- package/dist/store/buildProxy/handleLazyResolve.js +26 -0
- package/dist/store/buildProxy/handleLazyResolve.js.map +1 -0
- package/dist/store/buildProxy/initProxyCaches.d.ts +16 -0
- package/dist/store/buildProxy/initProxyCaches.d.ts.map +1 -0
- package/dist/store/buildProxy/initProxyCaches.js +17 -0
- package/dist/store/buildProxy/initProxyCaches.js.map +1 -0
- package/dist/store/compute/computeFieldState.d.ts +10 -0
- package/dist/store/compute/computeFieldState.d.ts.map +1 -0
- package/dist/store/compute/computeFieldState.js +53 -0
- package/dist/store/compute/computeFieldState.js.map +1 -0
- package/dist/store/compute/fieldStateChanged.d.ts +6 -0
- package/dist/store/compute/fieldStateChanged.d.ts.map +1 -0
- package/dist/store/compute/fieldStateChanged.js +20 -0
- package/dist/store/compute/fieldStateChanged.js.map +1 -0
- package/dist/store/compute/index.d.ts +7 -0
- package/dist/store/compute/index.d.ts.map +1 -0
- package/dist/store/compute/index.js +6 -0
- package/dist/store/compute/index.js.map +1 -0
- package/dist/store/compute/isEmpty.d.ts +6 -0
- package/dist/store/compute/isEmpty.d.ts.map +1 -0
- package/dist/store/compute/isEmpty.js +14 -0
- package/dist/store/compute/isEmpty.js.map +1 -0
- package/dist/store/compute/recompute/collectGroupComputeNodes.d.ts +11 -0
- package/dist/store/compute/recompute/collectGroupComputeNodes.d.ts.map +1 -0
- package/dist/store/compute/recompute/collectGroupComputeNodes.js +26 -0
- package/dist/store/compute/recompute/collectGroupComputeNodes.js.map +1 -0
- package/dist/store/compute/recompute/collectGroupLeafNodes.d.ts +11 -0
- package/dist/store/compute/recompute/collectGroupLeafNodes.d.ts.map +1 -0
- package/dist/store/compute/recompute/collectGroupLeafNodes.js +26 -0
- package/dist/store/compute/recompute/collectGroupLeafNodes.js.map +1 -0
- package/dist/store/compute/recompute/index.d.ts +7 -0
- package/dist/store/compute/recompute/index.d.ts.map +1 -0
- package/dist/store/compute/recompute/index.js +6 -0
- package/dist/store/compute/recompute/index.js.map +1 -0
- package/dist/store/compute/recompute/recomputeAndNotify.d.ts +8 -0
- package/dist/store/compute/recompute/recomputeAndNotify.d.ts.map +1 -0
- package/dist/store/compute/recompute/recomputeAndNotify.js +13 -0
- package/dist/store/compute/recompute/recomputeAndNotify.js.map +1 -0
- package/dist/store/compute/recompute/recomputeLeaves.d.ts +23 -0
- package/dist/store/compute/recompute/recomputeLeaves.d.ts.map +1 -0
- package/dist/store/compute/recompute/recomputeLeaves.js +77 -0
- package/dist/store/compute/recompute/recomputeLeaves.js.map +1 -0
- package/dist/store/compute/recompute/recomputeTargeted.d.ts +14 -0
- package/dist/store/compute/recompute/recomputeTargeted.d.ts.map +1 -0
- package/dist/store/compute/recompute/recomputeTargeted.js +50 -0
- package/dist/store/compute/recompute/recomputeTargeted.js.map +1 -0
- package/dist/store/compute/recompute/topologicalSortComputed.d.ts +16 -0
- package/dist/store/compute/recompute/topologicalSortComputed.d.ts.map +1 -0
- package/dist/store/compute/recompute/topologicalSortComputed.js +60 -0
- package/dist/store/compute/recompute/topologicalSortComputed.js.map +1 -0
- package/dist/store/compute/recompute/types.d.ts +24 -0
- package/dist/store/compute/recompute/types.d.ts.map +1 -0
- package/dist/store/compute/recompute/types.js +2 -0
- package/dist/store/compute/recompute/types.js.map +1 -0
- package/dist/store/compute/resolveFlag.d.ts +7 -0
- package/dist/store/compute/resolveFlag.d.ts.map +1 -0
- package/dist/store/compute/resolveFlag.js +12 -0
- package/dist/store/compute/resolveFlag.js.map +1 -0
- package/dist/store/compute/resolveString.d.ts +11 -0
- package/dist/store/compute/resolveString.d.ts.map +1 -0
- package/dist/store/compute/resolveString.js +18 -0
- package/dist/store/compute/resolveString.js.map +1 -0
- package/dist/store/compute/types.d.ts +37 -0
- package/dist/store/compute/types.d.ts.map +1 -0
- package/dist/store/compute/types.js +2 -0
- package/dist/store/compute/types.js.map +1 -0
- package/dist/store/constants.d.ts +83 -0
- package/dist/store/constants.d.ts.map +1 -0
- package/dist/store/constants.js +145 -0
- package/dist/store/constants.js.map +1 -0
- package/dist/store/defineFieldMapping.d.ts +41 -0
- package/dist/store/defineFieldMapping.d.ts.map +1 -0
- package/dist/store/defineFieldMapping.js +42 -0
- package/dist/store/defineFieldMapping.js.map +1 -0
- package/dist/store/defineList.d.ts +14 -0
- package/dist/store/defineList.d.ts.map +1 -0
- package/dist/store/defineList.js +7 -0
- package/dist/store/defineList.js.map +1 -0
- package/dist/store/dirtyTracking/captureInitialValues.d.ts +8 -0
- package/dist/store/dirtyTracking/captureInitialValues.d.ts.map +1 -0
- package/dist/store/dirtyTracking/captureInitialValues.js +16 -0
- package/dist/store/dirtyTracking/captureInitialValues.js.map +1 -0
- package/dist/store/dirtyTracking/collectInitialSnapshot.d.ts +10 -0
- package/dist/store/dirtyTracking/collectInitialSnapshot.d.ts.map +1 -0
- package/dist/store/dirtyTracking/collectInitialSnapshot.js +35 -0
- package/dist/store/dirtyTracking/collectInitialSnapshot.js.map +1 -0
- package/dist/store/dirtyTracking/index.d.ts +7 -0
- package/dist/store/dirtyTracking/index.d.ts.map +1 -0
- package/dist/store/dirtyTracking/index.js +6 -0
- package/dist/store/dirtyTracking/index.js.map +1 -0
- package/dist/store/dirtyTracking/isDirtyValue.d.ts +7 -0
- package/dist/store/dirtyTracking/isDirtyValue.d.ts.map +1 -0
- package/dist/store/dirtyTracking/isDirtyValue.js +25 -0
- package/dist/store/dirtyTracking/isDirtyValue.js.map +1 -0
- package/dist/store/dirtyTracking/mergeInitialValues.d.ts +11 -0
- package/dist/store/dirtyTracking/mergeInitialValues.d.ts.map +1 -0
- package/dist/store/dirtyTracking/mergeInitialValues.js +29 -0
- package/dist/store/dirtyTracking/mergeInitialValues.js.map +1 -0
- package/dist/store/dirtyTracking/recomputeDirtyTargeted.d.ts +17 -0
- package/dist/store/dirtyTracking/recomputeDirtyTargeted.d.ts.map +1 -0
- package/dist/store/dirtyTracking/recomputeDirtyTargeted.js +90 -0
- package/dist/store/dirtyTracking/recomputeDirtyTargeted.js.map +1 -0
- package/dist/store/dirtyTracking/setGroupRevalidate.d.ts +13 -0
- package/dist/store/dirtyTracking/setGroupRevalidate.d.ts.map +1 -0
- package/dist/store/dirtyTracking/setGroupRevalidate.js +32 -0
- package/dist/store/dirtyTracking/setGroupRevalidate.js.map +1 -0
- package/dist/store/entityRegistry/entityRegistry.d.ts +166 -0
- package/dist/store/entityRegistry/entityRegistry.d.ts.map +1 -0
- package/dist/store/entityRegistry/entityRegistry.js +402 -0
- package/dist/store/entityRegistry/entityRegistry.js.map +1 -0
- package/dist/store/entityRegistry/generateId.d.ts +7 -0
- package/dist/store/entityRegistry/generateId.d.ts.map +1 -0
- package/dist/store/entityRegistry/generateId.js +18 -0
- package/dist/store/entityRegistry/generateId.js.map +1 -0
- package/dist/store/entityRegistry/index.d.ts +4 -0
- package/dist/store/entityRegistry/index.d.ts.map +1 -0
- package/dist/store/entityRegistry/index.js +3 -0
- package/dist/store/entityRegistry/index.js.map +1 -0
- package/dist/store/entityRegistry/types.d.ts +50 -0
- package/dist/store/entityRegistry/types.d.ts.map +1 -0
- package/dist/store/entityRegistry/types.js +2 -0
- package/dist/store/entityRegistry/types.js.map +1 -0
- package/dist/store/fieldMapping.typecheck.d.ts +2 -0
- package/dist/store/fieldMapping.typecheck.d.ts.map +1 -0
- package/dist/store/fieldMapping.typecheck.js +71 -0
- package/dist/store/fieldMapping.typecheck.js.map +1 -0
- package/dist/store/groupDeps/createGroupDeps.d.ts +9 -0
- package/dist/store/groupDeps/createGroupDeps.d.ts.map +1 -0
- package/dist/store/groupDeps/createGroupDeps.js +29 -0
- package/dist/store/groupDeps/createGroupDeps.js.map +1 -0
- package/dist/store/groupDeps/createTrackingValues.d.ts +15 -0
- package/dist/store/groupDeps/createTrackingValues.d.ts.map +1 -0
- package/dist/store/groupDeps/createTrackingValues.js +39 -0
- package/dist/store/groupDeps/createTrackingValues.js.map +1 -0
- package/dist/store/groupDeps/getNodeGroupPath.d.ts +9 -0
- package/dist/store/groupDeps/getNodeGroupPath.d.ts.map +1 -0
- package/dist/store/groupDeps/getNodeGroupPath.js +20 -0
- package/dist/store/groupDeps/getNodeGroupPath.js.map +1 -0
- package/dist/store/groupDeps/getRecipientGroups.d.ts +5 -0
- package/dist/store/groupDeps/getRecipientGroups.d.ts.map +1 -0
- package/dist/store/groupDeps/getRecipientGroups.js +15 -0
- package/dist/store/groupDeps/getRecipientGroups.js.map +1 -0
- package/dist/store/groupDeps/groupDeps.d.ts +19 -0
- package/dist/store/groupDeps/groupDeps.d.ts.map +1 -0
- package/dist/store/groupDeps/groupDeps.js +19 -0
- package/dist/store/groupDeps/groupDeps.js.map +1 -0
- package/dist/store/groupDeps/index.d.ts +7 -0
- package/dist/store/groupDeps/index.d.ts.map +1 -0
- package/dist/store/groupDeps/index.js +7 -0
- package/dist/store/groupDeps/index.js.map +1 -0
- package/dist/store/groupDeps/pairKey.d.ts +7 -0
- package/dist/store/groupDeps/pairKey.d.ts.map +1 -0
- package/dist/store/groupDeps/pairKey.js +12 -0
- package/dist/store/groupDeps/pairKey.js.map +1 -0
- package/dist/store/groupDeps/resolveGroupByPath.d.ts +8 -0
- package/dist/store/groupDeps/resolveGroupByPath.d.ts.map +1 -0
- package/dist/store/groupDeps/resolveGroupByPath.js +19 -0
- package/dist/store/groupDeps/resolveGroupByPath.js.map +1 -0
- package/dist/store/init/createNotificationHub.d.ts +81 -0
- package/dist/store/init/createNotificationHub.d.ts.map +1 -0
- package/dist/store/init/createNotificationHub.js +149 -0
- package/dist/store/init/createNotificationHub.js.map +1 -0
- package/dist/store/init/createResolveManager.d.ts +166 -0
- package/dist/store/init/createResolveManager.d.ts.map +1 -0
- package/dist/store/init/createResolveManager.js +502 -0
- package/dist/store/init/createResolveManager.js.map +1 -0
- package/dist/store/init/initGroupSubmitting.d.ts +8 -0
- package/dist/store/init/initGroupSubmitting.d.ts.map +1 -0
- package/dist/store/init/initGroupSubmitting.js +39 -0
- package/dist/store/init/initGroupSubmitting.js.map +1 -0
- package/dist/store/normalizeConfig.d.ts +28 -0
- package/dist/store/normalizeConfig.d.ts.map +1 -0
- package/dist/store/normalizeConfig.js +76 -0
- package/dist/store/normalizeConfig.js.map +1 -0
- package/dist/store/onChangePipeline/computeFieldKey.d.ts +11 -0
- package/dist/store/onChangePipeline/computeFieldKey.d.ts.map +1 -0
- package/dist/store/onChangePipeline/computeFieldKey.js +18 -0
- package/dist/store/onChangePipeline/computeFieldKey.js.map +1 -0
- package/dist/store/onChangePipeline/findOnChangeAncestors.d.ts +8 -0
- package/dist/store/onChangePipeline/findOnChangeAncestors.d.ts.map +1 -0
- package/dist/store/onChangePipeline/findOnChangeAncestors.js +22 -0
- package/dist/store/onChangePipeline/findOnChangeAncestors.js.map +1 -0
- package/dist/store/onChangePipeline/onChangePipeline.d.ts +29 -0
- package/dist/store/onChangePipeline/onChangePipeline.d.ts.map +1 -0
- package/dist/store/onChangePipeline/onChangePipeline.js +99 -0
- package/dist/store/onChangePipeline/onChangePipeline.js.map +1 -0
- package/dist/store/persist/drivers.d.ts +34 -0
- package/dist/store/persist/drivers.d.ts.map +1 -0
- package/dist/store/persist/drivers.js +89 -0
- package/dist/store/persist/drivers.js.map +1 -0
- package/dist/store/persist/index.d.ts +7 -0
- package/dist/store/persist/index.d.ts.map +1 -0
- package/dist/store/persist/index.js +3 -0
- package/dist/store/persist/index.js.map +1 -0
- package/dist/store/persist/persistManager.d.ts +67 -0
- package/dist/store/persist/persistManager.d.ts.map +1 -0
- package/dist/store/persist/persistManager.js +198 -0
- package/dist/store/persist/persistManager.js.map +1 -0
- package/dist/store/persist/types.d.ts +66 -0
- package/dist/store/persist/types.d.ts.map +1 -0
- package/dist/store/persist/types.js +9 -0
- package/dist/store/persist/types.js.map +1 -0
- package/dist/store/resetPipeline/buildResetPatch.d.ts +11 -0
- package/dist/store/resetPipeline/buildResetPatch.d.ts.map +1 -0
- package/dist/store/resetPipeline/buildResetPatch.js +22 -0
- package/dist/store/resetPipeline/buildResetPatch.js.map +1 -0
- package/dist/store/resetPipeline/collectDefaults.d.ts +12 -0
- package/dist/store/resetPipeline/collectDefaults.d.ts.map +1 -0
- package/dist/store/resetPipeline/collectDefaults.js +31 -0
- package/dist/store/resetPipeline/collectDefaults.js.map +1 -0
- package/dist/store/resetPipeline/resetPipeline.d.ts +19 -0
- package/dist/store/resetPipeline/resetPipeline.d.ts.map +1 -0
- package/dist/store/resetPipeline/resetPipeline.js +49 -0
- package/dist/store/resetPipeline/resetPipeline.js.map +1 -0
- package/dist/store/resolvePipeline/applyPendingWrites.d.ts +26 -0
- package/dist/store/resolvePipeline/applyPendingWrites.d.ts.map +1 -0
- package/dist/store/resolvePipeline/applyPendingWrites.js +68 -0
- package/dist/store/resolvePipeline/applyPendingWrites.js.map +1 -0
- package/dist/store/resolvePipeline/createContextTrackingProxy.d.ts +16 -0
- package/dist/store/resolvePipeline/createContextTrackingProxy.d.ts.map +1 -0
- package/dist/store/resolvePipeline/createContextTrackingProxy.js +29 -0
- package/dist/store/resolvePipeline/createContextTrackingProxy.js.map +1 -0
- package/dist/store/resolvePipeline/createValuesTrackingProxy.d.ts +75 -0
- package/dist/store/resolvePipeline/createValuesTrackingProxy.d.ts.map +1 -0
- package/dist/store/resolvePipeline/createValuesTrackingProxy.js +128 -0
- package/dist/store/resolvePipeline/createValuesTrackingProxy.js.map +1 -0
- package/dist/store/resolvePipeline/executeEntityFieldResolve.d.ts +29 -0
- package/dist/store/resolvePipeline/executeEntityFieldResolve.d.ts.map +1 -0
- package/dist/store/resolvePipeline/executeEntityFieldResolve.js +218 -0
- package/dist/store/resolvePipeline/executeEntityFieldResolve.js.map +1 -0
- package/dist/store/resolvePipeline/executeListResolve.d.ts +32 -0
- package/dist/store/resolvePipeline/executeListResolve.d.ts.map +1 -0
- package/dist/store/resolvePipeline/executeListResolve.js +157 -0
- package/dist/store/resolvePipeline/executeListResolve.js.map +1 -0
- package/dist/store/resolvePipeline/executeResolve.d.ts +26 -0
- package/dist/store/resolvePipeline/executeResolve.d.ts.map +1 -0
- package/dist/store/resolvePipeline/executeResolve.js +201 -0
- package/dist/store/resolvePipeline/executeResolve.js.map +1 -0
- package/dist/store/resolvePipeline/findResolvesToRetrigger.d.ts +10 -0
- package/dist/store/resolvePipeline/findResolvesToRetrigger.d.ts.map +1 -0
- package/dist/store/resolvePipeline/findResolvesToRetrigger.js +29 -0
- package/dist/store/resolvePipeline/findResolvesToRetrigger.js.map +1 -0
- package/dist/store/resolvePipeline/index.d.ts +22 -0
- package/dist/store/resolvePipeline/index.d.ts.map +1 -0
- package/dist/store/resolvePipeline/index.js +18 -0
- package/dist/store/resolvePipeline/index.js.map +1 -0
- package/dist/store/resolvePipeline/initResolveStates.d.ts +41 -0
- package/dist/store/resolvePipeline/initResolveStates.d.ts.map +1 -0
- package/dist/store/resolvePipeline/initResolveStates.js +95 -0
- package/dist/store/resolvePipeline/initResolveStates.js.map +1 -0
- package/dist/store/resolvePipeline/resetResolveState.d.ts +8 -0
- package/dist/store/resolvePipeline/resetResolveState.d.ts.map +1 -0
- package/dist/store/resolvePipeline/resetResolveState.js +18 -0
- package/dist/store/resolvePipeline/resetResolveState.js.map +1 -0
- package/dist/store/resolvePipeline/types.d.ts +134 -0
- package/dist/store/resolvePipeline/types.d.ts.map +1 -0
- package/dist/store/resolvePipeline/types.js +54 -0
- package/dist/store/resolvePipeline/types.js.map +1 -0
- package/dist/store/store/NodeRegistry/index.d.ts +3 -0
- package/dist/store/store/NodeRegistry/index.d.ts.map +1 -0
- package/dist/store/store/NodeRegistry/index.js +2 -0
- package/dist/store/store/NodeRegistry/index.js.map +1 -0
- package/dist/store/store/NodeRegistry/nodeRegistry.d.ts +139 -0
- package/dist/store/store/NodeRegistry/nodeRegistry.d.ts.map +1 -0
- package/dist/store/store/NodeRegistry/nodeRegistry.js +255 -0
- package/dist/store/store/NodeRegistry/nodeRegistry.js.map +1 -0
- package/dist/store/store/NodeRegistry/nodeUtils.d.ts +17 -0
- package/dist/store/store/NodeRegistry/nodeUtils.d.ts.map +1 -0
- package/dist/store/store/NodeRegistry/nodeUtils.js +21 -0
- package/dist/store/store/NodeRegistry/nodeUtils.js.map +1 -0
- package/dist/store/store/NodeRegistry/nodeView.d.ts +28 -0
- package/dist/store/store/NodeRegistry/nodeView.d.ts.map +1 -0
- package/dist/store/store/NodeRegistry/nodeView.js +16 -0
- package/dist/store/store/NodeRegistry/nodeView.js.map +1 -0
- package/dist/store/store/dirtyTracker.d.ts +27 -0
- package/dist/store/store/dirtyTracker.d.ts.map +1 -0
- package/dist/store/store/dirtyTracker.js +38 -0
- package/dist/store/store/dirtyTracker.js.map +1 -0
- package/dist/store/store/groupDepsMap.d.ts +52 -0
- package/dist/store/store/groupDepsMap.d.ts.map +1 -0
- package/dist/store/store/groupDepsMap.js +84 -0
- package/dist/store/store/groupDepsMap.js.map +1 -0
- package/dist/store/store/hasComputedProps.d.ts +7 -0
- package/dist/store/store/hasComputedProps.d.ts.map +1 -0
- package/dist/store/store/hasComputedProps.js +15 -0
- package/dist/store/store/hasComputedProps.js.map +1 -0
- package/dist/store/store/index.d.ts +6 -0
- package/dist/store/store/index.d.ts.map +1 -0
- package/dist/store/store/index.js +3 -0
- package/dist/store/store/index.js.map +1 -0
- package/dist/store/store/nodeMap.d.ts +12 -0
- package/dist/store/store/nodeMap.d.ts.map +1 -0
- package/dist/store/store/nodeMap.js +30 -0
- package/dist/store/store/nodeMap.js.map +1 -0
- package/dist/store/store/palistor.d.ts +256 -0
- package/dist/store/store/palistor.d.ts.map +1 -0
- package/dist/store/store/palistor.js +772 -0
- package/dist/store/store/palistor.js.map +1 -0
- package/dist/store/store/registerNodes.d.ts +33 -0
- package/dist/store/store/registerNodes.d.ts.map +1 -0
- package/dist/store/store/registerNodes.js +88 -0
- package/dist/store/store/registerNodes.js.map +1 -0
- package/dist/store/store/serviceRegistry.d.ts +24 -0
- package/dist/store/store/serviceRegistry.d.ts.map +1 -0
- package/dist/store/store/serviceRegistry.js +32 -0
- package/dist/store/store/serviceRegistry.js.map +1 -0
- package/dist/store/store/types.d.ts +622 -0
- package/dist/store/store/types.d.ts.map +1 -0
- package/dist/store/store/types.js +2 -0
- package/dist/store/store/types.js.map +1 -0
- package/dist/store/submitPipeline/applyLeafBeforeSubmit.d.ts +7 -0
- package/dist/store/submitPipeline/applyLeafBeforeSubmit.d.ts.map +1 -0
- package/dist/store/submitPipeline/applyLeafBeforeSubmit.js +26 -0
- package/dist/store/submitPipeline/applyLeafBeforeSubmit.js.map +1 -0
- package/dist/store/submitPipeline/collectLeafStates.d.ts +11 -0
- package/dist/store/submitPipeline/collectLeafStates.d.ts.map +1 -0
- package/dist/store/submitPipeline/collectLeafStates.js +17 -0
- package/dist/store/submitPipeline/collectLeafStates.js.map +1 -0
- package/dist/store/submitPipeline/getSubValues.d.ts +9 -0
- package/dist/store/submitPipeline/getSubValues.d.ts.map +1 -0
- package/dist/store/submitPipeline/getSubValues.js +26 -0
- package/dist/store/submitPipeline/getSubValues.js.map +1 -0
- package/dist/store/submitPipeline/submitPipeline.d.ts +32 -0
- package/dist/store/submitPipeline/submitPipeline.d.ts.map +1 -0
- package/dist/store/submitPipeline/submitPipeline.js +119 -0
- package/dist/store/submitPipeline/submitPipeline.js.map +1 -0
- package/dist/store/submitPipeline/types.d.ts +12 -0
- package/dist/store/submitPipeline/types.d.ts.map +1 -0
- package/dist/store/submitPipeline/types.js +2 -0
- package/dist/store/submitPipeline/types.js.map +1 -0
- package/dist/store/traversal/index.d.ts +4 -0
- package/dist/store/traversal/index.d.ts.map +1 -0
- package/dist/store/traversal/index.js +3 -0
- package/dist/store/traversal/index.js.map +1 -0
- package/dist/store/traversal/nodeClassifier.d.ts +23 -0
- package/dist/store/traversal/nodeClassifier.d.ts.map +1 -0
- package/dist/store/traversal/nodeClassifier.js +46 -0
- package/dist/store/traversal/nodeClassifier.js.map +1 -0
- package/dist/store/traversal/walkFull.d.ts +33 -0
- package/dist/store/traversal/walkFull.d.ts.map +1 -0
- package/dist/store/traversal/walkFull.js +28 -0
- package/dist/store/traversal/walkFull.js.map +1 -0
- package/dist/store/valuesCache/valuesCache.d.ts +27 -0
- package/dist/store/valuesCache/valuesCache.d.ts.map +1 -0
- package/dist/store/valuesCache/valuesCache.js +58 -0
- package/dist/store/valuesCache/valuesCache.js.map +1 -0
- package/dist/store/writePipeline/formatPatch.d.ts +14 -0
- package/dist/store/writePipeline/formatPatch.d.ts.map +1 -0
- package/dist/store/writePipeline/formatPatch.js +35 -0
- package/dist/store/writePipeline/formatPatch.js.map +1 -0
- package/dist/store/writePipeline/formatValue.d.ts +12 -0
- package/dist/store/writePipeline/formatValue.d.ts.map +1 -0
- package/dist/store/writePipeline/formatValue.js +15 -0
- package/dist/store/writePipeline/formatValue.js.map +1 -0
- package/dist/store/writePipeline/index.d.ts +8 -0
- package/dist/store/writePipeline/index.d.ts.map +1 -0
- package/dist/store/writePipeline/index.js +7 -0
- package/dist/store/writePipeline/index.js.map +1 -0
- package/dist/store/writePipeline/mergeChanged.d.ts +9 -0
- package/dist/store/writePipeline/mergeChanged.d.ts.map +1 -0
- package/dist/store/writePipeline/mergeChanged.js +15 -0
- package/dist/store/writePipeline/mergeChanged.js.map +1 -0
- package/dist/store/writePipeline/runSetter.d.ts +16 -0
- package/dist/store/writePipeline/runSetter.d.ts.map +1 -0
- package/dist/store/writePipeline/runSetter.js +35 -0
- package/dist/store/writePipeline/runSetter.js.map +1 -0
- package/dist/store/writePipeline/storeValue.d.ts +11 -0
- package/dist/store/writePipeline/storeValue.d.ts.map +1 -0
- package/dist/store/writePipeline/storeValue.js +17 -0
- package/dist/store/writePipeline/storeValue.js.map +1 -0
- package/dist/store/writePipeline/types.d.ts +10 -0
- package/dist/store/writePipeline/types.d.ts.map +1 -0
- package/dist/store/writePipeline/types.js +2 -0
- package/dist/store/writePipeline/types.js.map +1 -0
- package/dist/store/writePipeline/writePipeline.d.ts +31 -0
- package/dist/store/writePipeline/writePipeline.d.ts.map +1 -0
- package/dist/store/writePipeline/writePipeline.js +97 -0
- package/dist/store/writePipeline/writePipeline.js.map +1 -0
- package/package.json +79 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Palistor - State Manager для форм
|
|
3
|
+
*
|
|
4
|
+
* Архитектура: createForm + useForm(id)
|
|
5
|
+
*
|
|
6
|
+
* createForm() вызывается на уровне модуля — задаёт статическую конфигурацию.
|
|
7
|
+
* useForm(id) вызывается в React-компоненте — привязывает к экземпляру.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* // config/orderForm.ts — модульный уровень
|
|
12
|
+
* import { createForm } from 'palistor';
|
|
13
|
+
* import { useTranslations } from 'next-intl';
|
|
14
|
+
*
|
|
15
|
+
* export const { useForm } = createForm<OrderValues>({
|
|
16
|
+
* config: orderConfig,
|
|
17
|
+
* defaults: orderDefaults,
|
|
18
|
+
* translateFunction: useTranslations,
|
|
19
|
+
* type: "Order",
|
|
20
|
+
* });
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* ```tsx
|
|
24
|
+
* // Корневой компонент — передаёт initial и колбэки
|
|
25
|
+
* const { getFieldProps, submit } = useForm(order?.id ?? "NewOrder", {
|
|
26
|
+
* initial: order,
|
|
27
|
+
* onSubmit: async (values) => { await api.saveOrder(values); },
|
|
28
|
+
* });
|
|
29
|
+
*
|
|
30
|
+
* return <Input {...getFieldProps("name")} />;
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* ```tsx
|
|
34
|
+
* // Вложенный компонент — подключается к существующему store
|
|
35
|
+
* const { getFieldProps } = useForm(orderId);
|
|
36
|
+
*
|
|
37
|
+
* return <Input {...getFieldProps("name")} />;
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export type { PersistDriver, PersistOptions } from "./store/persist/types";
|
|
41
|
+
export type { PersistManager } from "./store/persist/persistManager";
|
|
42
|
+
export { localStorageDriver, sessionStorageDriver } from "./store/persist/drivers";
|
|
43
|
+
export type { TranslateFn, FormConfig, MaybeComputed, MaybeTranslatable, DeepPartialValues, FieldTypeMeta, ConfigNode, FieldProxyNode, GroupProxyNode, ConfigProxy, FieldMapping, ApplyFieldMapping, ValidateExternalConfig, ConfigKeyError, ExternalConfig, ExternalConfigNode, RawStoreProxy, RawStoreProxyMarker, ExtractValues, ProxyStoreOptions, ProxyStore, Unsubscribe, PalistorRef, PalistorList, PalistorEntityProxy, TypedListNode, ListResolver, TemplateConfig, InferEntity, } from "./store/store/types";
|
|
44
|
+
export type { Palistor as PalistorProxy } from "./store/store/types";
|
|
45
|
+
export { Palistor } from "./store/store";
|
|
46
|
+
export type { Resolve, NotifyFn, ResolveErrorContext } from "./store/resolvePipeline/";
|
|
47
|
+
export { useNotifier } from "./react/useNotifier";
|
|
48
|
+
export { useForm } from "./react/useForm";
|
|
49
|
+
export { usePersist } from "./react/usePersist";
|
|
50
|
+
export { useTranslator } from "./react/useTranslator";
|
|
51
|
+
export { useStoreContext } from "./react/useStoreContext";
|
|
52
|
+
export { defineList } from "./store/defineList";
|
|
53
|
+
export { defineFieldMapping } from "./store/defineFieldMapping";
|
|
54
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAMH,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC3E,YAAY,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAMnF,YAAY,EACV,WAAW,EACX,UAAU,EACV,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,EACb,UAAU,EACV,cAAc,EACd,cAAc,EACd,WAAW,EACX,YAAY,EACZ,iBAAiB,EACjB,sBAAsB,EACtB,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,aAAa,EACb,mBAAmB,EACnB,aAAa,EACb,iBAAiB,EACjB,UAAU,EACV,WAAW,EACX,WAAW,EACX,YAAY,EACZ,mBAAmB,EACnB,aAAa,EACb,YAAY,EACZ,cAAc,EACd,WAAW,GACZ,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,QAAQ,IAAI,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACrE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAMzC,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACvF,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAMlD,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAM1D,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAMhD,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Palistor - State Manager для форм
|
|
3
|
+
*
|
|
4
|
+
* Архитектура: createForm + useForm(id)
|
|
5
|
+
*
|
|
6
|
+
* createForm() вызывается на уровне модуля — задаёт статическую конфигурацию.
|
|
7
|
+
* useForm(id) вызывается в React-компоненте — привязывает к экземпляру.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* // config/orderForm.ts — модульный уровень
|
|
12
|
+
* import { createForm } from 'palistor';
|
|
13
|
+
* import { useTranslations } from 'next-intl';
|
|
14
|
+
*
|
|
15
|
+
* export const { useForm } = createForm<OrderValues>({
|
|
16
|
+
* config: orderConfig,
|
|
17
|
+
* defaults: orderDefaults,
|
|
18
|
+
* translateFunction: useTranslations,
|
|
19
|
+
* type: "Order",
|
|
20
|
+
* });
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* ```tsx
|
|
24
|
+
* // Корневой компонент — передаёт initial и колбэки
|
|
25
|
+
* const { getFieldProps, submit } = useForm(order?.id ?? "NewOrder", {
|
|
26
|
+
* initial: order,
|
|
27
|
+
* onSubmit: async (values) => { await api.saveOrder(values); },
|
|
28
|
+
* });
|
|
29
|
+
*
|
|
30
|
+
* return <Input {...getFieldProps("name")} />;
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* ```tsx
|
|
34
|
+
* // Вложенный компонент — подключается к существующему store
|
|
35
|
+
* const { getFieldProps } = useForm(orderId);
|
|
36
|
+
*
|
|
37
|
+
* return <Input {...getFieldProps("name")} />;
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export { localStorageDriver, sessionStorageDriver } from "./store/persist/drivers";
|
|
41
|
+
export { Palistor } from "./store/store";
|
|
42
|
+
export { useNotifier } from "./react/useNotifier";
|
|
43
|
+
// ============================================================================
|
|
44
|
+
// React hooks
|
|
45
|
+
// ============================================================================
|
|
46
|
+
export { useForm } from "./react/useForm";
|
|
47
|
+
export { usePersist } from "./react/usePersist";
|
|
48
|
+
export { useTranslator } from "./react/useTranslator";
|
|
49
|
+
export { useStoreContext } from "./react/useStoreContext";
|
|
50
|
+
// ============================================================================
|
|
51
|
+
// defineList — typed list helper
|
|
52
|
+
// ============================================================================
|
|
53
|
+
export { defineList } from "./store/defineList";
|
|
54
|
+
// ============================================================================
|
|
55
|
+
// defineFieldMapping — typed fieldMapping helper (сохраняет литералы)
|
|
56
|
+
// ============================================================================
|
|
57
|
+
export { defineFieldMapping } from "./store/defineFieldMapping";
|
|
58
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAQH,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAsCnF,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAOzC,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAElD,+EAA+E;AAC/E,cAAc;AACd,+EAA+E;AAE/E,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE1D,+EAA+E;AAC/E,iCAAiC;AACjC,+EAA+E;AAE/E,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEhD,+EAA+E;AAC/E,sEAAsE;AACtE,+EAA+E;AAE/E,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* createTrackingProxy — оборачивает store.proxy во второй слой Proxy,
|
|
3
|
+
* который записывает, какие config-ноды были прочитаны компонентом.
|
|
4
|
+
*
|
|
5
|
+
* Каждый `useForm` вызов создаёт свой tracking proxy → свой tracked set.
|
|
6
|
+
* Это позволяет `getSnapshot` проверять версии только прочитанных нод
|
|
7
|
+
* и не вызывать re-render, если изменились поля, которые компонент не читает.
|
|
8
|
+
*
|
|
9
|
+
* Tracking работает на уровне ноды: чтение ЛЮБОГО свойства
|
|
10
|
+
* (value, label, isVisible…) добавляет всю ноду в tracked set.
|
|
11
|
+
*
|
|
12
|
+
* Списки: `items`, `map`, `length`, `loading`, `dirty` на list-proxy добавляют
|
|
13
|
+
* объект `ListState` (бренд LIST_STATE, единый для root и per-entity) в tracked
|
|
14
|
+
* set. Мутация/resolve бампает версию этого ListState → getSnapshot детектирует
|
|
15
|
+
* изменение → re-render только списка. `map` → entity-прокси оборачиваются в
|
|
16
|
+
* tracking proxy для per-leaf отслеживания строк.
|
|
17
|
+
*/
|
|
18
|
+
import type { ProxyStore } from "../store/store";
|
|
19
|
+
export interface TrackingRefs {
|
|
20
|
+
/** Набор config-нод, прочитанных компонентом. Только растёт (accumulate). */
|
|
21
|
+
accessed: Set<object>;
|
|
22
|
+
/** Версия каждой ноды на момент первого трекинга — для предотвращения
|
|
23
|
+
* ложных re-render сразу после добавления ноды в tracked set. */
|
|
24
|
+
lastVersions: Map<object, number>;
|
|
25
|
+
/**
|
|
26
|
+
* Компонент обращался к дочерним ключам (form.email, form.passport),
|
|
27
|
+
* но не читал FIELD_STATE_PROPS. Позволяет различить:
|
|
28
|
+
* - «навигация без чтения» (Parent передаёт поддерево пропсом) → стабильный snapshot
|
|
29
|
+
* - «ничего не трогал» (renderHook без JSX) → fallback на глобальную версию
|
|
30
|
+
*/
|
|
31
|
+
hasNavigated: boolean;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Проверить, является ли объект tracking proxy (имеет SOURCE_PROXY символ).
|
|
35
|
+
*/
|
|
36
|
+
export declare function isTrackingProxy(obj: unknown): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Извлечь source proxy и store из tracking proxy.
|
|
39
|
+
* Возвращает null если объект не является tracking proxy.
|
|
40
|
+
*/
|
|
41
|
+
export declare function unwrapTrackingProxy<TConfig extends Record<string, any>>(obj: unknown): {
|
|
42
|
+
sourceProxy: any;
|
|
43
|
+
store: ProxyStore<TConfig>;
|
|
44
|
+
} | null;
|
|
45
|
+
/**
|
|
46
|
+
* Создать tracking proxy поверх source proxy.
|
|
47
|
+
* Кэшируется по source proxy объектам (один tracking proxy на вложенный узел).
|
|
48
|
+
*
|
|
49
|
+
* @param sourceProxy — базовый Proxy из store.proxy (или его дочерний узел)
|
|
50
|
+
* @param refs — per-component tracking state (accessed, lastVersions)
|
|
51
|
+
* @param store — ProxyStore, для чтения текущих версий нод
|
|
52
|
+
* @param cache — WeakMap для кэширования tracking прокси объектов
|
|
53
|
+
*/
|
|
54
|
+
export declare function createTrackingProxy<TConfig extends Record<string, any>>(sourceProxy: any, refs: TrackingRefs, store: ProxyStore<TConfig>, cache: WeakMap<object, object>): any;
|
|
55
|
+
//# sourceMappingURL=createTrackingProxy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createTrackingProxy.d.ts","sourceRoot":"","sources":["../../react/createTrackingProxy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD,MAAM,WAAW,YAAY;IAC3B,6EAA6E;IAC7E,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACtB;sEACkE;IAClE,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC;;;;;OAKG;IACH,YAAY,EAAE,OAAO,CAAC;CACvB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAErD;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACrE,GAAG,EAAE,OAAO,GACX;IAAE,WAAW,EAAE,GAAG,CAAC;IAAC,KAAK,EAAE,UAAU,CAAC,OAAO,CAAC,CAAA;CAAE,GAAG,IAAI,CAMzD;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACrE,WAAW,EAAE,GAAG,EAChB,IAAI,EAAE,YAAY,EAClB,KAAK,EAAE,UAAU,CAAC,OAAO,CAAC,EAC1B,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,GAC7B,GAAG,CAuHL"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* createTrackingProxy — оборачивает store.proxy во второй слой Proxy,
|
|
3
|
+
* который записывает, какие config-ноды были прочитаны компонентом.
|
|
4
|
+
*
|
|
5
|
+
* Каждый `useForm` вызов создаёт свой tracking proxy → свой tracked set.
|
|
6
|
+
* Это позволяет `getSnapshot` проверять версии только прочитанных нод
|
|
7
|
+
* и не вызывать re-render, если изменились поля, которые компонент не читает.
|
|
8
|
+
*
|
|
9
|
+
* Tracking работает на уровне ноды: чтение ЛЮБОГО свойства
|
|
10
|
+
* (value, label, isVisible…) добавляет всю ноду в tracked set.
|
|
11
|
+
*
|
|
12
|
+
* Списки: `items`, `map`, `length`, `loading`, `dirty` на list-proxy добавляют
|
|
13
|
+
* объект `ListState` (бренд LIST_STATE, единый для root и per-entity) в tracked
|
|
14
|
+
* set. Мутация/resolve бампает версию этого ListState → getSnapshot детектирует
|
|
15
|
+
* изменение → re-render только списка. `map` → entity-прокси оборачиваются в
|
|
16
|
+
* tracking proxy для per-leaf отслеживания строк.
|
|
17
|
+
*/
|
|
18
|
+
import { FIELD_STATE_PROPS, CONFIG_NODE, SOURCE_PROXY, STORE_REF, ENTITY_ID_LEAF, LIST_STATE } from "../store/constants";
|
|
19
|
+
/**
|
|
20
|
+
* Проверить, является ли объект tracking proxy (имеет SOURCE_PROXY символ).
|
|
21
|
+
*/
|
|
22
|
+
export function isTrackingProxy(obj) {
|
|
23
|
+
return !!obj && typeof obj === "object" && !!obj[SOURCE_PROXY];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Извлечь source proxy и store из tracking proxy.
|
|
27
|
+
* Возвращает null если объект не является tracking proxy.
|
|
28
|
+
*/
|
|
29
|
+
export function unwrapTrackingProxy(obj) {
|
|
30
|
+
if (!isTrackingProxy(obj))
|
|
31
|
+
return null;
|
|
32
|
+
return {
|
|
33
|
+
sourceProxy: obj[SOURCE_PROXY],
|
|
34
|
+
store: obj[STORE_REF],
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Создать tracking proxy поверх source proxy.
|
|
39
|
+
* Кэшируется по source proxy объектам (один tracking proxy на вложенный узел).
|
|
40
|
+
*
|
|
41
|
+
* @param sourceProxy — базовый Proxy из store.proxy (или его дочерний узел)
|
|
42
|
+
* @param refs — per-component tracking state (accessed, lastVersions)
|
|
43
|
+
* @param store — ProxyStore, для чтения текущих версий нод
|
|
44
|
+
* @param cache — WeakMap для кэширования tracking прокси объектов
|
|
45
|
+
*/
|
|
46
|
+
export function createTrackingProxy(sourceProxy, refs, store, cache) {
|
|
47
|
+
if (cache.has(sourceProxy))
|
|
48
|
+
return cache.get(sourceProxy);
|
|
49
|
+
const tracked = new Proxy(sourceProxy, {
|
|
50
|
+
get(target, key) {
|
|
51
|
+
// CONFIG_NODE — пробрасываем, tracking proxy прозрачен для этого символа
|
|
52
|
+
if (key === CONFIG_NODE)
|
|
53
|
+
return target[CONFIG_NODE];
|
|
54
|
+
// SOURCE_PROXY — возвращаем исходный store proxy (target tracking proxy)
|
|
55
|
+
if (key === SOURCE_PROXY)
|
|
56
|
+
return target;
|
|
57
|
+
// STORE_REF — возвращаем ссылку на ProxyStore
|
|
58
|
+
if (key === STORE_REF)
|
|
59
|
+
return store;
|
|
60
|
+
// Прочие символы — пробрасываем как есть
|
|
61
|
+
if (typeof key === "symbol")
|
|
62
|
+
return target[key];
|
|
63
|
+
// Обратный маппинг на входе: external → internal. Проверки состояния
|
|
64
|
+
// (list-ключи, FIELD_STATE_PROPS) — по `ikey`; читаем и навигируем по
|
|
65
|
+
// оригинальному external-`key` (source-proxy переведёт его обратно).
|
|
66
|
+
const ikey = (store.externalToInternal[key] ?? key);
|
|
67
|
+
// ── List proxy (единый кубик: root + per-entity) ───────────────────────
|
|
68
|
+
// Ключ трекинга = объект ListState, а НЕ общий listConfigNode: иначе версии
|
|
69
|
+
// разных владельцев одного per-entity-списка схлопнутся (RFC §2.6), а root
|
|
70
|
+
// и entity потребовали бы две ветки. Должно идти ДО FIELD_STATE_PROPS:
|
|
71
|
+
// `loading`/`dirty` входят в FIELD_STATE_PROPS, но на списке их надо трекать
|
|
72
|
+
// по ListState, а не по CONFIG_NODE.
|
|
73
|
+
const listState = target[LIST_STATE];
|
|
74
|
+
if (listState) {
|
|
75
|
+
if (ikey === "length" || ikey === "loading" || ikey === "dirty") {
|
|
76
|
+
if (!refs.accessed.has(listState)) {
|
|
77
|
+
refs.accessed.add(listState);
|
|
78
|
+
refs.lastVersions.set(listState, store.getNodeVersion(listState));
|
|
79
|
+
}
|
|
80
|
+
return target[key];
|
|
81
|
+
}
|
|
82
|
+
if (ikey === "items") {
|
|
83
|
+
if (!refs.accessed.has(listState)) {
|
|
84
|
+
refs.accessed.add(listState);
|
|
85
|
+
refs.lastVersions.set(listState, store.getNodeVersion(listState));
|
|
86
|
+
}
|
|
87
|
+
const rawItems = target[key];
|
|
88
|
+
return rawItems.map((item) => createTrackingProxy(item, refs, store, cache));
|
|
89
|
+
}
|
|
90
|
+
if (ikey === "map") {
|
|
91
|
+
if (!refs.accessed.has(listState)) {
|
|
92
|
+
refs.accessed.add(listState);
|
|
93
|
+
refs.lastVersions.set(listState, store.getNodeVersion(listState));
|
|
94
|
+
}
|
|
95
|
+
const origMap = target[key];
|
|
96
|
+
return (fn) => origMap((item, index, id) => fn(createTrackingProxy(item, refs, store, cache), index, id));
|
|
97
|
+
}
|
|
98
|
+
// add/remove/setItems/getById — пробрасываем без трекинга.
|
|
99
|
+
return target[key];
|
|
100
|
+
}
|
|
101
|
+
// Чтение состояния поля → трекинг ноды
|
|
102
|
+
// submitting — реактивный флаг группы, тоже требует трекинга
|
|
103
|
+
if (FIELD_STATE_PROPS.has(ikey) || ikey === "submitting") {
|
|
104
|
+
const configNode = target[CONFIG_NODE];
|
|
105
|
+
if (configNode && !refs.accessed.has(configNode)) {
|
|
106
|
+
refs.accessed.add(configNode);
|
|
107
|
+
// Сохраняем текущую версию, чтобы getSnapshot не считал это изменением
|
|
108
|
+
refs.lastVersions.set(configNode, store.getNodeVersion(configNode));
|
|
109
|
+
}
|
|
110
|
+
return target[key];
|
|
111
|
+
}
|
|
112
|
+
// Дочерний объект → рекурсивный tracking proxy
|
|
113
|
+
const result = target[key];
|
|
114
|
+
// Entity id access: the entity proxy returns the id string directly (not via a
|
|
115
|
+
// leaf proxy), so we would normally miss tracking it. Detect by checking if the
|
|
116
|
+
// entity proxy exposes ENTITY_ID_LEAF and register that leaf for subscriptions.
|
|
117
|
+
// This ensures rekey() → idLeaf version bump → getSnapshot detects change → re-render.
|
|
118
|
+
if (key === "id") {
|
|
119
|
+
const idLeaf = target[ENTITY_ID_LEAF];
|
|
120
|
+
if (idLeaf && !refs.accessed.has(idLeaf)) {
|
|
121
|
+
refs.accessed.add(idLeaf);
|
|
122
|
+
refs.lastVersions.set(idLeaf, store.getNodeVersion(idLeaf));
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
if (result && typeof result === "object") {
|
|
126
|
+
refs.hasNavigated = true;
|
|
127
|
+
return createTrackingProxy(result, refs, store, cache);
|
|
128
|
+
}
|
|
129
|
+
return result;
|
|
130
|
+
},
|
|
131
|
+
set(target, key, value) {
|
|
132
|
+
// Запись пробрасывается в исходный proxy (SET trap в buildProxy)
|
|
133
|
+
return Reflect.set(target, key, value);
|
|
134
|
+
},
|
|
135
|
+
/**
|
|
136
|
+
* Пробрасываем ownKeys из source proxy, чтобы spread ({...trackingProxy})
|
|
137
|
+
* возвращал те же ключи, что и store proxy (без validate, formatter, …).
|
|
138
|
+
*/
|
|
139
|
+
ownKeys(target) {
|
|
140
|
+
return Reflect.ownKeys(target);
|
|
141
|
+
},
|
|
142
|
+
getOwnPropertyDescriptor(target, key) {
|
|
143
|
+
return Reflect.getOwnPropertyDescriptor(target, key);
|
|
144
|
+
},
|
|
145
|
+
});
|
|
146
|
+
cache.set(sourceProxy, tracked);
|
|
147
|
+
return tracked;
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=createTrackingProxy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createTrackingProxy.js","sourceRoot":"","sources":["../../react/createTrackingProxy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useForm — React хук для подключения к ProxyStore
|
|
3
|
+
*
|
|
4
|
+
* Возвращает реактивный прокси. Доступ к полям через точку — это и есть
|
|
5
|
+
* подписка: компонент перерендерится только при изменении прочитанных полей.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```tsx
|
|
9
|
+
* const store = new Palistor({ config });
|
|
10
|
+
*
|
|
11
|
+
* function App() {
|
|
12
|
+
* const form = useForm(store);
|
|
13
|
+
*
|
|
14
|
+
* return (
|
|
15
|
+
* <div>
|
|
16
|
+
* <PassportSection passport={form.passport} />
|
|
17
|
+
* <input
|
|
18
|
+
* value={form.email.value}
|
|
19
|
+
* onChange={(e) => { form.email.value = e.target.value }}
|
|
20
|
+
* />
|
|
21
|
+
* </div>
|
|
22
|
+
* );
|
|
23
|
+
* }
|
|
24
|
+
*
|
|
25
|
+
* // Дочерний компонент с useForm для независимой подписки:
|
|
26
|
+
* function PassportSection({ passport }) {
|
|
27
|
+
* const p = useForm(passport); // ← принимает поддерево!
|
|
28
|
+
* if (!p.isVisible) return null;
|
|
29
|
+
* return <NumberField field={p.number} />;
|
|
30
|
+
* }
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* Как работает:
|
|
34
|
+
* 1. useSyncExternalStore подписывается на глобальные изменения store.
|
|
35
|
+
* 2. getSnapshot сравнивает версии только прочитанных узлов →
|
|
36
|
+
* re-render происходит только если изменилось то, что читалось.
|
|
37
|
+
* 3. store.proxy оборачивается в tracking proxy. Каждый GET записывает
|
|
38
|
+
* config-ноду в tracked set. getSnapshot проверяет только эти ноды.
|
|
39
|
+
* 4. Запись `form.email.value = "X"` → store.proxy.email.value = "X" →
|
|
40
|
+
* SET trap → formatter → validate → recompute → notify → re-render
|
|
41
|
+
* (только компонентов, которые читали изменившиеся ноды).
|
|
42
|
+
*
|
|
43
|
+
* Перегрузки:
|
|
44
|
+
* - useForm(store) — основной вариант, передаём ProxyStore
|
|
45
|
+
* - useForm(proxySubtree) — принимает tracking proxy поддерево (из пропса),
|
|
46
|
+
* создаёт **независимый** tracking для этого компонента
|
|
47
|
+
* - useForm(entityProxy, templateSelector) — привязка entity к template.
|
|
48
|
+
* entityProxy из list.items/list.getById. templateSelector = (s) => s.editForm.
|
|
49
|
+
* Вызывает entityRegistry.bind на mount, unbind на unmount.
|
|
50
|
+
*/
|
|
51
|
+
import type { ProxyStore, ConfigProxy, GroupProxyNode, RawStoreProxyMarker } from "../store/store";
|
|
52
|
+
import type { PalistorRef, PalistorList, Palistor, PalistorEntityProxy, FieldMapping } from "../store/store/types";
|
|
53
|
+
/**
|
|
54
|
+
* Подключает React-компонент к ProxyStore.
|
|
55
|
+
*
|
|
56
|
+
* Компонент перерендерится только при изменении полей, которые он читал
|
|
57
|
+
* во время предыдущего рендера. Tracking proxy автоматически записывает
|
|
58
|
+
* обращения к FIELD_STATE_PROPS (value, label, isVisible, error…) и
|
|
59
|
+
* getSnapshot проверяет версии только этих нод.
|
|
60
|
+
*
|
|
61
|
+
* На первом рендере tracked set пуст → используется глобальная версия
|
|
62
|
+
* (fallback). После первого рендера tracking работает точечно.
|
|
63
|
+
*
|
|
64
|
+
* @param input — ProxyStore, созданный через new Palistor(), ИЛИ
|
|
65
|
+
* tracking proxy поддерево (из пропса другого useForm)
|
|
66
|
+
* @returns tracking proxy — типизированный по конфигу (или поддереву)
|
|
67
|
+
*/
|
|
68
|
+
/**
|
|
69
|
+
* Тип-«ошибка», который TypeScript показывает в диагностике, если в
|
|
70
|
+
* `useForm` передали сырой `store.proxy` или его поддерево. Имя интерфейса
|
|
71
|
+
* специально длинное и описательное — оно появится в тексте ошибки и
|
|
72
|
+
* подскажет, что делать.
|
|
73
|
+
*
|
|
74
|
+
* @see {@link RawStoreProxyMarker}
|
|
75
|
+
*/
|
|
76
|
+
export interface _PALISTOR_ERROR__do_not_pass_store_proxy_subtree_to_useForm__call_useForm_store_first {
|
|
77
|
+
readonly _palistorError: "useForm received a raw store.proxy subtree. Use: const form = useForm(store); then drill into form.subtree (a tracking proxy). See useForm-raw-proxy-pitfall.md.";
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Превращает T в тип-ошибку, если T помечен {@link RawStoreProxyMarker}.
|
|
81
|
+
* Применяется к параметру subtree-перегрузки `useForm`, чтобы сделать
|
|
82
|
+
* `useForm(store.proxy.subtree)` ошибкой компиляции.
|
|
83
|
+
*/
|
|
84
|
+
type ForbidRawStoreProxy<T> = T extends RawStoreProxyMarker ? _PALISTOR_ERROR__do_not_pass_store_proxy_subtree_to_useForm__call_useForm_store_first : T;
|
|
85
|
+
export declare function useForm<T extends Record<string, any>>(input: PalistorRef<T>): PalistorEntityProxy<T>;
|
|
86
|
+
export declare function useForm<T extends Record<string, any>>(input: PalistorList<T>): PalistorList<T>;
|
|
87
|
+
export declare function useForm<T extends Record<string, any> & {
|
|
88
|
+
id?: any;
|
|
89
|
+
}>(input: Palistor<T>): PalistorEntityProxy<T>;
|
|
90
|
+
export declare function useForm<T extends GroupProxyNode>(input: ForbidRawStoreProxy<T>): T;
|
|
91
|
+
export declare function useForm<TConfig extends Record<string, any>, TMapping extends FieldMapping = {}>(input: ProxyStore<TConfig, TMapping>): ConfigProxy<TConfig, TMapping>;
|
|
92
|
+
/**
|
|
93
|
+
* Перегрузка: привязка entity к template для отображения/редактирования.
|
|
94
|
+
*
|
|
95
|
+
* @param entity — EntityProjectionProxy из list.items или list.getById
|
|
96
|
+
* @param templateSelector — функция выбора template: (store) => store.editUserForm
|
|
97
|
+
* @returns tracking proxy entity через template (поля template + значения entity)
|
|
98
|
+
*
|
|
99
|
+
* Lifecycle:
|
|
100
|
+
* - mount: entityRegistry.bind(entityId, templateNode)
|
|
101
|
+
* - unmount: entityRegistry.unbind(entityId, templateNode)
|
|
102
|
+
*
|
|
103
|
+
* Resolved cache (3A.4): при повторном открытии той же entity+template
|
|
104
|
+
* `isResolved` возвращает true → resolve будет пропущен (Phase 3B).
|
|
105
|
+
*/
|
|
106
|
+
export declare function useForm(entity: object, templateSelector: (store: any) => any): any;
|
|
107
|
+
export {};
|
|
108
|
+
//# sourceMappingURL=useForm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useForm.d.ts","sourceRoot":"","sources":["../../react/useForm.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACnG,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AA2CnH;;;;;;;;;;;;;;GAcG;AACH;;;;;;;GAOG;AACH,MAAM,WAAW,qFAAqF;IACpG,QAAQ,CAAC,cAAc,EACrB,kKAAkK,CAAC;CACtK;AAED;;;;GAIG;AACH,KAAK,mBAAmB,CAAC,CAAC,IAAI,CAAC,SAAS,mBAAmB,GACvD,qFAAqF,GACrF,CAAC,CAAC;AAEN,wBAAgB,OAAO,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,mBAAmB,CAAC,CAAC,CAAC,CAAC;AACtG,wBAAgB,OAAO,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;AAChG,wBAAgB,OAAO,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG;IAAE,EAAE,CAAC,EAAE,GAAG,CAAA;CAAE,EAClE,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,GACjB,mBAAmB,CAAC,CAAC,CAAC,CAAC;AAC1B,wBAAgB,OAAO,CAAC,CAAC,SAAS,cAAc,EAC9C,KAAK,EAAE,mBAAmB,CAAC,CAAC,CAAC,GAC5B,CAAC,CAAC;AAEL,wBAAgB,OAAO,CACrB,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACnC,QAAQ,SAAS,YAAY,GAAG,EAAE,EAElC,KAAK,EAAE,UAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,GACnC,WAAW,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;AAElC;;;;;;;;;;;;;GAaG;AACH,wBAAgB,OAAO,CACrB,MAAM,EAAE,MAAM,EACd,gBAAgB,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,GAAG,GACpC,GAAG,CAAC"}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useForm — React хук для подключения к ProxyStore
|
|
3
|
+
*
|
|
4
|
+
* Возвращает реактивный прокси. Доступ к полям через точку — это и есть
|
|
5
|
+
* подписка: компонент перерендерится только при изменении прочитанных полей.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```tsx
|
|
9
|
+
* const store = new Palistor({ config });
|
|
10
|
+
*
|
|
11
|
+
* function App() {
|
|
12
|
+
* const form = useForm(store);
|
|
13
|
+
*
|
|
14
|
+
* return (
|
|
15
|
+
* <div>
|
|
16
|
+
* <PassportSection passport={form.passport} />
|
|
17
|
+
* <input
|
|
18
|
+
* value={form.email.value}
|
|
19
|
+
* onChange={(e) => { form.email.value = e.target.value }}
|
|
20
|
+
* />
|
|
21
|
+
* </div>
|
|
22
|
+
* );
|
|
23
|
+
* }
|
|
24
|
+
*
|
|
25
|
+
* // Дочерний компонент с useForm для независимой подписки:
|
|
26
|
+
* function PassportSection({ passport }) {
|
|
27
|
+
* const p = useForm(passport); // ← принимает поддерево!
|
|
28
|
+
* if (!p.isVisible) return null;
|
|
29
|
+
* return <NumberField field={p.number} />;
|
|
30
|
+
* }
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* Как работает:
|
|
34
|
+
* 1. useSyncExternalStore подписывается на глобальные изменения store.
|
|
35
|
+
* 2. getSnapshot сравнивает версии только прочитанных узлов →
|
|
36
|
+
* re-render происходит только если изменилось то, что читалось.
|
|
37
|
+
* 3. store.proxy оборачивается в tracking proxy. Каждый GET записывает
|
|
38
|
+
* config-ноду в tracked set. getSnapshot проверяет только эти ноды.
|
|
39
|
+
* 4. Запись `form.email.value = "X"` → store.proxy.email.value = "X" →
|
|
40
|
+
* SET trap → formatter → validate → recompute → notify → re-render
|
|
41
|
+
* (только компонентов, которые читали изменившиеся ноды).
|
|
42
|
+
*
|
|
43
|
+
* Перегрузки:
|
|
44
|
+
* - useForm(store) — основной вариант, передаём ProxyStore
|
|
45
|
+
* - useForm(proxySubtree) — принимает tracking proxy поддерево (из пропса),
|
|
46
|
+
* создаёт **независимый** tracking для этого компонента
|
|
47
|
+
* - useForm(entityProxy, templateSelector) — привязка entity к template.
|
|
48
|
+
* entityProxy из list.items/list.getById. templateSelector = (s) => s.editForm.
|
|
49
|
+
* Вызывает entityRegistry.bind на mount, unbind на unmount.
|
|
50
|
+
*/
|
|
51
|
+
import { useSyncExternalStore, useCallback, useRef, useMemo, useEffect } from "react";
|
|
52
|
+
import { createTrackingProxy, unwrapTrackingProxy, } from "./createTrackingProxy";
|
|
53
|
+
import { ENTITY_ID, STORE_REF, CONFIG_NODE } from "../store/constants";
|
|
54
|
+
import { buildEntityProjectionProxy } from "../store/buildProxy/buildEntityProjectionProxy";
|
|
55
|
+
/**
|
|
56
|
+
* Извлечь store и sourceProxy из аргумента useForm.
|
|
57
|
+
* Поддерживает ProxyStore напрямую и tracking proxy поддеревья.
|
|
58
|
+
*/
|
|
59
|
+
function resolveInput(input) {
|
|
60
|
+
// Если это tracking proxy (поддерево переданное пропсом)
|
|
61
|
+
const unwrapped = unwrapTrackingProxy(input);
|
|
62
|
+
if (unwrapped)
|
|
63
|
+
return unwrapped;
|
|
64
|
+
// Сырой GroupProxyNode из store.proxy.someGroup — НЕ подходит.
|
|
65
|
+
// Пользователь должен передавать либо ProxyStore (new Palistor()),
|
|
66
|
+
// либо tracking proxy (из пропса родительского useForm).
|
|
67
|
+
if (input != null && typeof input === "object" && input[CONFIG_NODE]) {
|
|
68
|
+
throw new Error("useForm: получен сырой proxy-узел стора (store.proxy.someGroup). " +
|
|
69
|
+
"Это не допустимо.\n\n" +
|
|
70
|
+
"Правильный способ:\n" +
|
|
71
|
+
" 1. Получите tracking proxy через useForm(store):\n" +
|
|
72
|
+
" const form = useForm(store);\n" +
|
|
73
|
+
" 2. Передайте поддерево как проп дочернему компоненту:\n" +
|
|
74
|
+
" <Child section={form.someGroup} />\n" +
|
|
75
|
+
" 3. В дочернем компоненте вызовите useForm(props.section).\n\n" +
|
|
76
|
+
"Нельзя передавать store.proxy или его дочерние узлы напрямую в useForm.");
|
|
77
|
+
}
|
|
78
|
+
// Иначе это ProxyStore — берём store.proxy как sourceProxy
|
|
79
|
+
return { store: input, sourceProxy: input.proxy };
|
|
80
|
+
}
|
|
81
|
+
export function useForm(input, templateSelector) {
|
|
82
|
+
// ─── Detect entity mode ──────────────────────────────────────────────────
|
|
83
|
+
const isEntityMode = typeof templateSelector === "function";
|
|
84
|
+
const entityMetaRef = useRef(null);
|
|
85
|
+
if (isEntityMode && !entityMetaRef.current) {
|
|
86
|
+
const entityId = input[ENTITY_ID];
|
|
87
|
+
const entityStore = input[STORE_REF];
|
|
88
|
+
if (!entityId || !entityStore) {
|
|
89
|
+
throw new Error("useForm: first argument must be an entity proxy (from list.items or list.getById) " +
|
|
90
|
+
"when templateSelector is provided.");
|
|
91
|
+
}
|
|
92
|
+
const templateProxy = templateSelector(entityStore.proxy);
|
|
93
|
+
const templateNode = templateProxy[CONFIG_NODE];
|
|
94
|
+
if (!templateNode) {
|
|
95
|
+
throw new Error("useForm: templateSelector must return a group proxy node.");
|
|
96
|
+
}
|
|
97
|
+
const entityNode = entityStore.entityRegistry.get(entityId);
|
|
98
|
+
if (!entityNode) {
|
|
99
|
+
throw new Error(`useForm: entity "${entityId}" not found in registry.`);
|
|
100
|
+
}
|
|
101
|
+
const entityProxy = buildEntityProjectionProxy(entityNode, templateNode, entityStore, new WeakMap());
|
|
102
|
+
entityMetaRef.current = { entityId, entityStore, templateNode, entityProxy };
|
|
103
|
+
}
|
|
104
|
+
// ─── Standard mode: resolve store + sourceProxy ──────────────────────────
|
|
105
|
+
const { store: stdStore, sourceProxy: stdSourceProxy } = useMemo(() => isEntityMode
|
|
106
|
+
? { store: null, sourceProxy: null }
|
|
107
|
+
: resolveInput(input),
|
|
108
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
109
|
+
[input, isEntityMode]);
|
|
110
|
+
// ─── Unified store + sourceProxy ────────────────────────────────────────
|
|
111
|
+
const store = isEntityMode
|
|
112
|
+
? entityMetaRef.current.entityStore
|
|
113
|
+
: stdStore;
|
|
114
|
+
const sourceProxy = isEntityMode
|
|
115
|
+
? entityMetaRef.current.entityProxy
|
|
116
|
+
: stdSourceProxy;
|
|
117
|
+
// ─── Tracking state (per-component, стабильные ref-ы) ────────────────────
|
|
118
|
+
const refsRef = useRef(null);
|
|
119
|
+
if (!refsRef.current) {
|
|
120
|
+
refsRef.current = {
|
|
121
|
+
accessed: new Set(),
|
|
122
|
+
lastVersions: new Map(),
|
|
123
|
+
hasNavigated: false,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
const refs = refsRef.current;
|
|
127
|
+
const cacheRef = useRef(null);
|
|
128
|
+
if (!cacheRef.current)
|
|
129
|
+
cacheRef.current = new WeakMap();
|
|
130
|
+
const snapshotRef = useRef(0);
|
|
131
|
+
// ─── Tracking proxy ───────────────────────────────────────────────────────
|
|
132
|
+
const trackingProxy = useMemo(() => createTrackingProxy(sourceProxy, refs, store, cacheRef.current), [store, sourceProxy, refs]);
|
|
133
|
+
// ─── Bind/unbind lifecycle (entity mode only) ────────────────────────────
|
|
134
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
135
|
+
useEffect(() => {
|
|
136
|
+
if (!isEntityMode)
|
|
137
|
+
return;
|
|
138
|
+
const meta = entityMetaRef.current;
|
|
139
|
+
if (!meta)
|
|
140
|
+
return;
|
|
141
|
+
// Привязываем entity к template — регистрируем, что этот шаблон сейчас отображает данную entity
|
|
142
|
+
meta.entityStore.entityRegistry.bind(meta.entityId, meta.templateNode);
|
|
143
|
+
// Запускаем resolve на уровне template, если он ещё не выполнялся для этой entity+template пары
|
|
144
|
+
if (!meta.entityStore.entityRegistry.isResolved(meta.entityId, meta.templateNode)) {
|
|
145
|
+
meta.entityStore.resolveManager.triggerEntityTemplateResolve(meta.entityId, meta.templateNode, meta.entityProxy);
|
|
146
|
+
}
|
|
147
|
+
// Per-field resolves are now triggered lazily from the entity leaf proxy GET trap
|
|
148
|
+
// (on first access to .value or .loading) — no eager loop needed here.
|
|
149
|
+
return () => {
|
|
150
|
+
// При размонтировании отвязываем entity от template — шаблон больше не отображает эту entity
|
|
151
|
+
meta.entityStore.entityRegistry.unbind(meta.entityId, meta.templateNode);
|
|
152
|
+
};
|
|
153
|
+
}, []); // bind once on mount, unbind on unmount
|
|
154
|
+
// ─── useSyncExternalStore ────────────────────────────────────────────────
|
|
155
|
+
const subscribe = useCallback((onStoreChange) => store.subscribeGlobal(onStoreChange), [store]);
|
|
156
|
+
const getSnapshot = useCallback(() => {
|
|
157
|
+
const { accessed, lastVersions } = refs;
|
|
158
|
+
if (accessed.size === 0) {
|
|
159
|
+
return refs.hasNavigated ? snapshotRef.current : store.getVersion();
|
|
160
|
+
}
|
|
161
|
+
let changed = false;
|
|
162
|
+
for (const node of accessed) {
|
|
163
|
+
const currentVersion = store.getNodeVersion(node);
|
|
164
|
+
if (currentVersion !== lastVersions.get(node)) {
|
|
165
|
+
changed = true;
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
if (changed) {
|
|
170
|
+
snapshotRef.current = store.getVersion();
|
|
171
|
+
for (const node of accessed) {
|
|
172
|
+
lastVersions.set(node, store.getNodeVersion(node));
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return snapshotRef.current;
|
|
176
|
+
}, [store, refs]);
|
|
177
|
+
useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
178
|
+
return trackingProxy;
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=useForm.js.map
|