@regle/core 1.4.0-beta.2 → 1.4.1-beta.1

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.
@@ -211,8 +211,8 @@ function getFunctionParametersLength(func) {
211
211
  //#endregion
212
212
  //#region src/core/createRule/defineRuleProcessors.ts
213
213
  function defineRuleProcessors(definition, ...params) {
214
- const { validator, type } = definition;
215
- const isAsync = type === InternalRuleType.Async || validator.constructor.name === "AsyncFunction";
214
+ const { validator, type, async } = definition;
215
+ const isAsync = async || type === InternalRuleType.Async || validator.constructor.name === "AsyncFunction";
216
216
  const defaultProcessors = {
217
217
  validator(value, ...args) {
218
218
  return definition.validator(value, ...unwrapRuleParameters(args.length ? args : params));
@@ -255,6 +255,7 @@ function defineRuleProcessors(definition, ...params) {
255
255
  };
256
256
  const processors = markRaw({
257
257
  ...defaultProcessors,
258
+ type,
258
259
  _validator: definition.validator,
259
260
  _message: definition.message,
260
261
  _active: definition.active,
@@ -305,8 +306,11 @@ function defineRuleProcessors(definition, ...params) {
305
306
  function createRule(definition) {
306
307
  if (typeof definition.validator === "function") {
307
308
  let fakeParams = [];
308
- const staticProcessors = defineRuleProcessors(definition, ...fakeParams);
309
309
  const isAsync = definition.async ?? definition.validator.constructor.name === "AsyncFunction";
310
+ const staticProcessors = defineRuleProcessors({
311
+ ...definition,
312
+ async: isAsync
313
+ }, ...fakeParams);
310
314
  if (getFunctionParametersLength(definition.validator) > 1) {
311
315
  const ruleFactory = function(...params) {
312
316
  return defineRuleProcessors(definition, ...params);
@@ -577,28 +581,41 @@ function extractRulesIssues({ field, silent = false }) {
577
581
  $message: message,
578
582
  $property: field.fieldName,
579
583
  $rule: key,
580
- $type: rule.$type
584
+ $type: rule.$type,
585
+ ...typeof rule.$metadata === "object" ? rule.$metadata : {}
581
586
  };
582
587
  return issue;
583
588
  });
584
- return issues.filter((msg) => !!msg).reduce((acc, issue) => {
585
- if (typeof issue.$message === "string") return acc?.concat([issue]);
586
- else return acc?.concat(issue.$message.map((msg) => ({
589
+ const filteredIssues = issues.filter((msg) => !!msg);
590
+ const ruleIssues = filteredIssues.reduce((acc, issue) => {
591
+ if (typeof issue.$message === "string") acc.push(issue);
592
+ else acc.push(...issue.$message.map((msg) => ({
587
593
  ...issue,
588
594
  $message: msg
589
595
  })));
590
- }, []).concat(field.$error ? field.$externalErrors?.map((error) => ({
596
+ return acc;
597
+ }, []);
598
+ const externalIssues = field.$error && field.$externalErrors ? field.$externalErrors.map((error) => ({
591
599
  $message: error,
592
600
  $property: field.fieldName,
593
601
  $rule: "external",
594
602
  $type: void 0
595
- })) ?? [] : []).concat(field.$error ? field.$schemaErrors ?? [] : []);
603
+ })) : [];
604
+ const schemaIssues = field.$error ? field.$schemaErrors ?? [] : [];
605
+ return [
606
+ ...ruleIssues,
607
+ ...externalIssues,
608
+ ...schemaIssues
609
+ ];
596
610
  }
597
611
  function extractRulesTooltips({ field }) {
598
- return Object.entries(field.$rules ?? {}).map(([_, rule]) => rule.$tooltip).filter((tooltip) => !!tooltip).reduce((acc, value) => {
599
- if (typeof value === "string") return acc?.concat([value]);
600
- else return acc?.concat(value);
601
- }, []);
612
+ const tooltips = [];
613
+ for (const rule of Object.values(field.$rules ?? {})) {
614
+ const tooltip = rule.$tooltip;
615
+ if (tooltip) if (typeof tooltip === "string") tooltips.push(tooltip);
616
+ else tooltips.push(...tooltip);
617
+ }
618
+ return tooltips;
602
619
  }
603
620
  function isCollectionError(errors) {
604
621
  return isObject(errors) && "$each" in errors;
@@ -635,13 +652,13 @@ function iterateErrors(errors, includePath = false, _path) {
635
652
 
636
653
  //#endregion
637
654
  //#region src/core/useRegle/root/createReactiveRuleStatus.ts
638
- function createReactiveRuleStatus({ customMessages, rule, ruleKey, state, path, storage, $debounce, modifiers }) {
655
+ function createReactiveRuleStatus({ customMessages, rule, ruleKey, state, path, cachePath, storage, $debounce, modifiers }) {
639
656
  let scope = effectScope();
640
657
  let scopeState = {};
641
658
  let $unwatchState;
642
659
  const $haveAsync = ref(false);
643
660
  const $maybePending = ref(false);
644
- const { $pending, $valid, $metadata, $validating } = storage.trySetRuleStatusRef(`${path}.${ruleKey}`);
661
+ const { $pending, $valid, $metadata, $validating } = storage.trySetRuleStatusRef(`${cachePath}.${ruleKey}`);
645
662
  function $watch() {
646
663
  scope = effectScope();
647
664
  scopeState = scope.run(() => {
@@ -811,70 +828,71 @@ function createReactiveRuleStatus({ customMessages, rule, ruleKey, state, path,
811
828
 
812
829
  //#endregion
813
830
  //#region src/core/useRegle/root/createReactiveFieldStatus.ts
814
- function createReactiveFieldStatus({ state, rulesDef, customMessages, path, fieldName, storage, options, externalErrors, schemaErrors, schemaMode, onUnwatch, $isArray, initialState, shortcuts, onValidate }) {
831
+ function createReactiveFieldStatus({ state, rulesDef, customMessages, path, cachePath, fieldName, storage, options, externalErrors, schemaErrors, schemaMode, onUnwatch, $isArray, initialState, shortcuts, onValidate }) {
815
832
  let scope = effectScope();
816
833
  let scopeState;
817
834
  let fieldScopes = [];
818
835
  let $unwatchState;
819
- let $unwatchValid;
820
836
  let $unwatchDirty;
821
837
  let $unwatchAsync;
822
838
  let $unwatchRuleFieldValues;
823
839
  let $commit = () => {};
824
840
  function createReactiveRulesResult() {
825
841
  const declaredRules = rulesDef.value;
826
- const storeResult = storage.checkRuleDeclEntry(path, declaredRules);
827
- $localOptions.value = Object.fromEntries(Object.entries(declaredRules).filter(([ruleKey]) => ruleKey.startsWith("$")));
842
+ const storeResult = storage.checkRuleDeclEntry(cachePath, declaredRules);
843
+ const options$1 = {};
844
+ for (const key in declaredRules) if (key.startsWith("$")) options$1[key] = declaredRules[key];
845
+ $localOptions.value = options$1;
828
846
  $watch();
829
- $rules.value = Object.fromEntries(Object.entries(rulesDef.value).filter(([ruleKey]) => !ruleKey.startsWith("$")).map(([ruleKey, rule]) => {
830
- if (rule) {
831
- const ruleRef = toRef(() => rule);
832
- return [ruleKey, createReactiveRuleStatus({
833
- modifiers: {
834
- $silent: scopeState.$silent,
835
- $rewardEarly: scopeState.$rewardEarly
836
- },
837
- customMessages,
838
- rule: ruleRef,
839
- ruleKey,
840
- state,
841
- path,
842
- storage,
843
- $debounce: $localOptions.value.$debounce
844
- })];
845
- }
846
- return [];
847
- }).filter((ruleDef) => !!ruleDef.length));
847
+ const rules = rulesDef.value;
848
+ const entries = [];
849
+ for (const ruleKey in rules) {
850
+ if (ruleKey.startsWith("$")) continue;
851
+ const rule = rules[ruleKey];
852
+ if (!rule) continue;
853
+ const ruleRef = toRef(() => rule);
854
+ entries.push([ruleKey, createReactiveRuleStatus({
855
+ modifiers: {
856
+ $silent: scopeState.$silent,
857
+ $rewardEarly: scopeState.$rewardEarly
858
+ },
859
+ customMessages,
860
+ rule: ruleRef,
861
+ ruleKey,
862
+ state,
863
+ path,
864
+ cachePath,
865
+ storage,
866
+ $debounce: $localOptions.value.$debounce
867
+ })]);
868
+ }
869
+ $rules.value = Object.fromEntries(entries);
848
870
  scopeState.processShortcuts();
849
871
  define$commit();
850
872
  if (storeResult?.valid != null) {
851
- scopeState.$dirty.value = storage.getDirtyState(path);
873
+ scopeState.$dirty.value = storage.getDirtyState(cachePath);
852
874
  if (scopeState.$dirty.value && !scopeState.$silent.value || scopeState.$rewardEarly.value && scopeState.$error.value) $commit();
853
875
  }
854
- storage.addRuleDeclEntry(path, declaredRules);
876
+ storage.addRuleDeclEntry(cachePath, declaredRules);
855
877
  }
856
878
  function define$commit() {
857
879
  $commit = scopeState.$debounce.value ? debounce($commitHandler, scopeState.$debounce.value ?? scopeState.$haveAnyAsyncRule ? 100 : 0) : $commitHandler;
858
880
  }
859
881
  function $unwatch() {
860
- if ($rules.value) Object.entries($rules.value).forEach(([_, rule]) => {
861
- rule.$unwatch();
862
- });
882
+ if ($rules.value) for (const rule of Object.values($rules.value)) rule.$unwatch();
863
883
  $unwatchDirty();
864
884
  $unwatchRuleFieldValues?.();
865
- if (scopeState.$dirty.value) storage.setDirtyEntry(path, scopeState.$dirty.value);
885
+ if (scopeState.$dirty.value) storage.setDirtyEntry(cachePath, scopeState.$dirty.value);
866
886
  $unwatchState?.();
867
887
  scope.stop();
868
888
  scope = effectScope();
869
- fieldScopes.forEach((s) => s.stop());
889
+ for (const s of fieldScopes) s.stop();
870
890
  fieldScopes = [];
871
891
  onUnwatch?.();
872
892
  $unwatchAsync?.();
873
893
  }
874
894
  function $watch() {
875
- if ($rules.value) Object.entries($rules.value).forEach(([_, rule]) => {
876
- rule.$watch();
877
- });
895
+ if ($rules.value) for (const rule of Object.values($rules.value)) rule.$watch();
878
896
  scopeState = scope.run(() => {
879
897
  const $dirty = ref(false);
880
898
  const triggerPunishment = ref(false);
@@ -914,9 +932,8 @@ function createReactiveFieldStatus({ state, rulesDef, customMessages, path, fiel
914
932
  return true;
915
933
  });
916
934
  const $validating$1 = computed(() => {
917
- return Object.entries($rules.value).some(([key, ruleResult]) => {
918
- return ruleResult.$validating;
919
- });
935
+ for (const ruleResult of Object.values($rules.value)) if (ruleResult.$validating) return true;
936
+ return false;
920
937
  });
921
938
  const $silentValue = computed({
922
939
  get: () => state.value,
@@ -982,34 +999,28 @@ function createReactiveFieldStatus({ state, rulesDef, customMessages, path, fiel
982
999
  const $invalid = computed(() => {
983
1000
  if (externalErrors?.value?.length || schemaErrors?.value?.length) return true;
984
1001
  else if ($inactive.value) return false;
985
- else if (!$rewardEarly$1.value || $rewardEarly$1.value) {
986
- const result = Object.entries($rules.value).some(([_, ruleResult]) => {
987
- return !(ruleResult.$valid && !ruleResult.$maybePending);
988
- });
989
- return result;
990
- }
1002
+ else if (!$rewardEarly$1.value || $rewardEarly$1.value) return Object.values($rules.value).some((ruleResult) => !ruleResult.$valid || ruleResult.$maybePending);
991
1003
  return false;
992
1004
  });
993
1005
  const $name = computed(() => fieldName);
994
1006
  const $inactive = computed(() => {
995
- if (Object.keys(rulesDef.value).filter(([ruleKey]) => !ruleKey.startsWith("$")).length === 0 && !schemaMode) return true;
996
- return false;
1007
+ return !schemaMode && !Object.keys(rulesDef.value).some((key) => !key.startsWith("$"));
997
1008
  });
998
1009
  const $correct = computed(() => {
999
1010
  if (externalErrors?.value?.length) return false;
1000
1011
  else if ($inactive.value) return false;
1001
1012
  else if ($dirty.value && !isEmpty(state.value) && !$validating$1.value && !$pending.value) if (schemaMode) return !schemaErrors?.value?.length;
1002
1013
  else {
1003
- const atLeastOneActiveRule = Object.values($rules.value).some((ruleResult) => ruleResult.$active);
1004
- if (atLeastOneActiveRule) return Object.values($rules.value).filter((ruleResult) => ruleResult.$active).every((ruleResult) => ruleResult.$valid);
1005
- else return false;
1014
+ const rules = Object.values($rules.value);
1015
+ for (const rule of rules) if (rule.$active) {
1016
+ if (!rule.$valid) return false;
1017
+ }
1018
+ return rules.some((rule) => rule.$active);
1006
1019
  }
1007
1020
  return false;
1008
1021
  });
1009
1022
  const $haveAnyAsyncRule$1 = computed(() => {
1010
- return Object.entries($rules.value).some(([key, ruleResult]) => {
1011
- return ruleResult.$haveAsync;
1012
- });
1023
+ return Object.values($rules.value).some((rule) => rule.$haveAsync);
1013
1024
  });
1014
1025
  function processShortcuts() {
1015
1026
  if (shortcuts?.fields) Object.entries(shortcuts.fields).forEach(([key, value]) => {
@@ -1077,7 +1088,7 @@ function createReactiveFieldStatus({ state, rulesDef, customMessages, path, fiel
1077
1088
  });
1078
1089
  define$watchState();
1079
1090
  $unwatchDirty = watch(scopeState.$dirty, (newDirty) => {
1080
- storage.setDirtyEntry(path, newDirty);
1091
+ storage.setDirtyEntry(cachePath, newDirty);
1081
1092
  Object.values($rules.value).forEach((rule) => {
1082
1093
  rule.$fieldDirty = newDirty;
1083
1094
  });
@@ -1118,7 +1129,7 @@ function createReactiveFieldStatus({ state, rulesDef, customMessages, path, fiel
1118
1129
  function $reset(options$1, fromParent) {
1119
1130
  $clearExternalErrors();
1120
1131
  scopeState.$dirty.value = false;
1121
- storage.setDirtyEntry(path, false);
1132
+ storage.setDirtyEntry(cachePath, false);
1122
1133
  if (!fromParent) if (options$1?.toInitialState) state.value = cloneDeep(initialState.value);
1123
1134
  else if (options$1?.toState) {
1124
1135
  let newInitialState;
@@ -1128,12 +1139,8 @@ function createReactiveFieldStatus({ state, rulesDef, customMessages, path, fiel
1128
1139
  state.value = cloneDeep(newInitialState);
1129
1140
  } else initialState.value = isObject(state.value) ? cloneDeep(state.value) : Array.isArray(state.value) ? [...state.value] : state.value;
1130
1141
  if (options$1?.clearExternalErrors) $clearExternalErrors();
1131
- if (!fromParent) Object.entries($rules.value).forEach(([_, rule]) => {
1132
- rule.$reset();
1133
- });
1134
- if (!scopeState.$lazy.value && !scopeState.$silent.value && !fromParent) Object.values($rules.value).forEach((rule) => {
1135
- return rule.$parse();
1136
- });
1142
+ if (!fromParent) for (const rule of Object.values($rules.value)) rule.$reset();
1143
+ if (!scopeState.$lazy.value && !scopeState.$silent.value && !fromParent) for (const rule of Object.values($rules.value)) rule.$parse();
1137
1144
  }
1138
1145
  function $touch(runCommit = true, withConditions = false) {
1139
1146
  if (!scopeState.$dirty.value) scopeState.$dirty.value = true;
@@ -1164,13 +1171,8 @@ function createReactiveFieldStatus({ state, rulesDef, customMessages, path, fiel
1164
1171
  valid: true,
1165
1172
  data
1166
1173
  };
1167
- const results = await Promise.allSettled(Object.entries($rules.value).map(([key, rule]) => {
1168
- return rule.$parse();
1169
- }));
1170
- const validationResults = results.every((value) => {
1171
- if (value.status === "fulfilled") return value.value === true;
1172
- else return false;
1173
- });
1174
+ const results = await Promise.allSettled(Object.values($rules.value).map((rule) => rule.$parse()));
1175
+ const validationResults = results.every((value) => value.status === "fulfilled" && value.value === true);
1174
1176
  return {
1175
1177
  valid: validationResults,
1176
1178
  data
@@ -1198,6 +1200,7 @@ function createReactiveFieldStatus({ state, rulesDef, customMessages, path, fiel
1198
1200
  $value: state,
1199
1201
  $rules,
1200
1202
  ...$shortcuts,
1203
+ $path: path,
1201
1204
  $reset,
1202
1205
  $touch,
1203
1206
  $validate,
@@ -1210,16 +1213,17 @@ function createReactiveFieldStatus({ state, rulesDef, customMessages, path, fiel
1210
1213
 
1211
1214
  //#endregion
1212
1215
  //#region src/core/useRegle/root/collections/createReactiveCollectionElement.ts
1213
- function createCollectionElement({ $id, path, index, options, storage, stateValue, customMessages, rules, externalErrors, schemaErrors, initialState, shortcuts, fieldName, schemaMode }) {
1216
+ function createCollectionElement({ $id, path, cachePath, index, options, storage, stateValue, customMessages, rules, externalErrors, schemaErrors, initialState, shortcuts, fieldName, schemaMode }) {
1214
1217
  const $fieldId = rules.$key ? rules.$key : randomId();
1215
- let $path = `${path}.${String($fieldId)}`;
1218
+ let $cachePath = `${path}.${String($fieldId)}`;
1219
+ let $path = `${path}.${index}`;
1216
1220
  if (typeof stateValue.value === "object" && stateValue.value != null) if (!stateValue.value.$id) Object.defineProperties(stateValue.value, { $id: {
1217
1221
  value: $fieldId,
1218
1222
  enumerable: false,
1219
1223
  configurable: false,
1220
1224
  writable: false
1221
1225
  } });
1222
- else $path = `${path}.${stateValue.value.$id}`;
1226
+ else $cachePath = `${path}.${stateValue.value.$id}`;
1223
1227
  const $externalErrors = toRef(externalErrors?.value ?? [], index);
1224
1228
  const $schemaErrors = computed(() => schemaErrors?.value?.[index]);
1225
1229
  const $status = createReactiveChildrenStatus({
@@ -1227,6 +1231,7 @@ function createCollectionElement({ $id, path, index, options, storage, stateValu
1227
1231
  rulesDef: toRef(() => rules),
1228
1232
  customMessages,
1229
1233
  path: $path,
1234
+ cachePath: $cachePath,
1230
1235
  storage,
1231
1236
  options,
1232
1237
  externalErrors: $externalErrors,
@@ -1294,6 +1299,7 @@ function createReactiveCollectionStatus({ state, rulesDef, customMessages, path,
1294
1299
  const element = createCollectionElement({
1295
1300
  $id: $id.value,
1296
1301
  path,
1302
+ cachePath: path,
1297
1303
  customMessages,
1298
1304
  rules: unwrapped ?? {},
1299
1305
  stateValue: toRef(() => value),
@@ -1316,6 +1322,7 @@ function createReactiveCollectionStatus({ state, rulesDef, customMessages, path,
1316
1322
  rulesDef,
1317
1323
  customMessages,
1318
1324
  path,
1325
+ cachePath: path,
1319
1326
  storage,
1320
1327
  options,
1321
1328
  externalErrors: toRef(externalErrors?.value ?? {}, `$self`),
@@ -1347,6 +1354,7 @@ function createReactiveCollectionStatus({ state, rulesDef, customMessages, path,
1347
1354
  const element = createCollectionElement({
1348
1355
  $id: $id.value,
1349
1356
  path,
1357
+ cachePath: path,
1350
1358
  customMessages,
1351
1359
  rules: unwrapped ?? {},
1352
1360
  stateValue: currentValue,
@@ -1437,6 +1445,12 @@ function createReactiveCollectionStatus({ state, rulesDef, customMessages, path,
1437
1445
  return statusOrField.$anyEdited;
1438
1446
  });
1439
1447
  });
1448
+ const $issues = computed(() => {
1449
+ return {
1450
+ $self: $selfStatus.value.$issues,
1451
+ $each: $eachStatus.value.map(($each) => $each.$issues)
1452
+ };
1453
+ });
1440
1454
  const $errors = computed(() => {
1441
1455
  return {
1442
1456
  $self: $selfStatus.value.$errors,
@@ -1475,20 +1489,22 @@ function createReactiveCollectionStatus({ state, rulesDef, customMessages, path,
1475
1489
  result.value = value(reactive({
1476
1490
  $dirty,
1477
1491
  $error,
1492
+ $path: path,
1478
1493
  $silentValue,
1479
1494
  $pending,
1480
1495
  $invalid,
1481
1496
  $correct,
1482
1497
  $errors,
1483
- $ready,
1484
1498
  $silentErrors,
1499
+ $ready,
1485
1500
  $anyDirty,
1486
1501
  $name,
1487
1502
  $each: $eachStatus,
1488
1503
  $self: $selfStatus,
1489
1504
  $value: state,
1490
1505
  $edited,
1491
- $anyEdited
1506
+ $anyEdited,
1507
+ $issues
1492
1508
  }));
1493
1509
  });
1494
1510
  return result;
@@ -1515,7 +1531,8 @@ function createReactiveCollectionStatus({ state, rulesDef, customMessages, path,
1515
1531
  $anyEdited,
1516
1532
  $rewardEarly,
1517
1533
  $silent,
1518
- $autoDirty
1534
+ $autoDirty,
1535
+ $issues
1519
1536
  };
1520
1537
  });
1521
1538
  if (immediateScopeState.isPrimitiveArray.value && rulesDef.value.$each) console.warn(`${path} is a Array of primitives. Tracking can be lost when reassigning the Array. We advise to use an Array of objects instead`);
@@ -1599,6 +1616,7 @@ function createReactiveCollectionStatus({ state, rulesDef, customMessages, path,
1599
1616
  $self: $selfStatus,
1600
1617
  ...restScopeState,
1601
1618
  ...$shortcuts,
1619
+ $path: path,
1602
1620
  $each: $eachStatus,
1603
1621
  $value: state,
1604
1622
  $validate,
@@ -1613,7 +1631,7 @@ function createReactiveCollectionStatus({ state, rulesDef, customMessages, path,
1613
1631
 
1614
1632
  //#endregion
1615
1633
  //#region src/core/useRegle/root/createReactiveNestedStatus.ts
1616
- function createReactiveNestedStatus({ rulesDef, state, path = "", rootRules, externalErrors, schemaErrors, rootSchemaErrors, validationGroups, initialState, fieldName,...commonArgs }) {
1634
+ function createReactiveNestedStatus({ rulesDef, state, path = "", cachePath, rootRules, externalErrors, schemaErrors, rootSchemaErrors, validationGroups, initialState, fieldName,...commonArgs }) {
1617
1635
  let scope = effectScope();
1618
1636
  let scopeState;
1619
1637
  let nestedScopes = [];
@@ -1624,35 +1642,38 @@ function createReactiveNestedStatus({ rulesDef, state, path = "", rootRules, ext
1624
1642
  let $unwatchGroups = null;
1625
1643
  async function createReactiveFieldsStatus(watchSources = true) {
1626
1644
  const mapOfRulesDef = Object.entries(rulesDef.value);
1627
- const scopedRulesStatus = Object.fromEntries(mapOfRulesDef.filter(([_, rule]) => !!rule).map(([statePropKey, statePropRules]) => {
1628
- if (statePropRules) {
1629
- const stateRef = toRef(state.value ?? {}, statePropKey);
1630
- const statePropRulesRef = toRef(() => statePropRules);
1631
- const $externalErrors = toRef(externalErrors?.value ?? {}, statePropKey);
1632
- const $schemaErrors = computed(() => schemaErrors?.value?.[statePropKey]);
1633
- const initialStateRef = toRef(initialState?.value ?? {}, statePropKey);
1634
- return [statePropKey, createReactiveChildrenStatus({
1635
- state: stateRef,
1636
- rulesDef: statePropRulesRef,
1637
- path: path ? `${path}.${statePropKey}` : statePropKey,
1638
- externalErrors: $externalErrors,
1639
- schemaErrors: $schemaErrors,
1640
- initialState: initialStateRef,
1641
- fieldName: statePropKey,
1642
- ...commonArgs
1643
- })];
1644
- }
1645
- return [];
1646
- }));
1645
+ const scopedRulesStatus = Object.fromEntries(mapOfRulesDef.reduce((acc, [statePropKey, statePropRules]) => {
1646
+ if (!statePropRules) return acc;
1647
+ const stateRef = toRef(state.value ?? {}, statePropKey);
1648
+ const statePropRulesRef = toRef(() => statePropRules);
1649
+ const $externalErrors = toRef(externalErrors?.value ?? {}, statePropKey);
1650
+ const $schemaErrors = computed(() => schemaErrors?.value?.[statePropKey]);
1651
+ const initialStateRef = toRef(initialState?.value ?? {}, statePropKey);
1652
+ acc.push([statePropKey, createReactiveChildrenStatus({
1653
+ state: stateRef,
1654
+ rulesDef: statePropRulesRef,
1655
+ path: path ? `${path}.${statePropKey}` : statePropKey,
1656
+ cachePath: cachePath ? `${cachePath}.${statePropKey}` : statePropKey,
1657
+ externalErrors: $externalErrors,
1658
+ schemaErrors: $schemaErrors,
1659
+ initialState: initialStateRef,
1660
+ fieldName: statePropKey,
1661
+ ...commonArgs
1662
+ })]);
1663
+ return acc;
1664
+ }, []));
1647
1665
  const externalRulesStatus = Object.fromEntries(Object.entries(unref(externalErrors) ?? {}).filter(([key, errors]) => !(key in rulesDef.value) && !!errors).map(([key]) => {
1648
1666
  const stateRef = toRef(state.value ?? {}, key);
1649
1667
  const $externalErrors = toRef(externalErrors?.value ?? {}, key);
1650
1668
  const $schemaErrors = computed(() => schemaErrors?.value?.[key]);
1651
1669
  const initialStateRef = toRef(initialState?.value ?? {}, key);
1670
+ const computedPath = path ? `${path}.${key}` : key;
1671
+ const computedCachePath = cachePath ? `${cachePath}.${key}` : key;
1652
1672
  return [key, createReactiveChildrenStatus({
1653
1673
  state: stateRef,
1654
1674
  rulesDef: computed(() => ({})),
1655
- path: path ? `${path}.${key}` : key,
1675
+ path: computedPath,
1676
+ cachePath: computedCachePath,
1656
1677
  externalErrors: $externalErrors,
1657
1678
  schemaErrors: $schemaErrors,
1658
1679
  initialState: initialStateRef,
@@ -1661,14 +1682,18 @@ function createReactiveNestedStatus({ rulesDef, state, path = "", rootRules, ext
1661
1682
  })];
1662
1683
  }));
1663
1684
  const schemasRulesStatus = Object.fromEntries(Object.entries(unref(schemaErrors) ?? {}).map(([key]) => {
1685
+ const computedPath = path ? `${path}.${key}` : key;
1686
+ const computedCachePath = cachePath ? `${cachePath}.${key}` : key;
1664
1687
  const stateRef = toRef(state.value ?? {}, key);
1665
1688
  const $externalErrors = toRef(externalErrors?.value ?? {}, key);
1666
1689
  const $schemaErrors = computed(() => schemaErrors?.value?.[key]);
1667
1690
  const initialStateRef = toRef(initialState?.value ?? {}, key);
1691
+ const emptyRulesDef = computed(() => ({}));
1668
1692
  return [key, createReactiveChildrenStatus({
1669
1693
  state: stateRef,
1670
- rulesDef: computed(() => ({})),
1671
- path: path ? `${path}.${key}` : key,
1694
+ rulesDef: emptyRulesDef,
1695
+ path: computedPath,
1696
+ cachePath: computedCachePath,
1672
1697
  externalErrors: $externalErrors,
1673
1698
  schemaErrors: $schemaErrors,
1674
1699
  initialState: initialStateRef,
@@ -1685,6 +1710,7 @@ function createReactiveNestedStatus({ rulesDef, state, path = "", rootRules, ext
1685
1710
  state: stateRef,
1686
1711
  rulesDef: computed(() => ({})),
1687
1712
  path: path ? `${path}.${key}` : key,
1713
+ cachePath: cachePath ? `${cachePath}.${key}` : key,
1688
1714
  externalErrors: $externalErrors,
1689
1715
  schemaErrors: $schemaErrors,
1690
1716
  initialState: initialStateRef,
@@ -1757,39 +1783,44 @@ function createReactiveNestedStatus({ rulesDef, state, path = "", rootRules, ext
1757
1783
  }
1758
1784
  });
1759
1785
  const $dirty = computed(() => {
1760
- return !!Object.entries($fields.value).length && Object.entries($fields.value).every(([_, statusOrField]) => {
1761
- return statusOrField?.$dirty;
1762
- });
1786
+ const fields = $fields.value;
1787
+ const fieldKeys = Object.keys(fields);
1788
+ if (!fieldKeys.length) return false;
1789
+ for (const key of fieldKeys) if (!fields[key]?.$dirty) return false;
1790
+ return true;
1763
1791
  });
1764
1792
  const $anyDirty = computed(() => {
1765
- return Object.entries($fields.value).some(([_, statusOrField]) => {
1766
- return statusOrField?.$anyDirty;
1767
- });
1793
+ const fields = $fields.value;
1794
+ for (const key in fields) if (fields[key]?.$anyDirty) return true;
1795
+ return false;
1768
1796
  });
1769
1797
  const $invalid = computed(() => {
1770
- return !!Object.entries($fields.value).length && Object.entries($fields.value).some(([_, statusOrField]) => {
1771
- return statusOrField?.$invalid;
1772
- });
1798
+ const fields = $fields.value;
1799
+ const entries = Object.entries(fields);
1800
+ if (!entries.length) return false;
1801
+ for (const [_, statusOrField] of entries) if (statusOrField?.$invalid) return true;
1802
+ return false;
1773
1803
  });
1774
1804
  const $correct = computed(() => {
1775
- const fields = Object.entries($fields.value).filter(([_, statusOrField]) => {
1776
- if (isFieldStatus(statusOrField)) return !statusOrField.$inactive;
1777
- return true;
1778
- });
1779
- if (fields.length) return fields.every(([_, statusOrField]) => {
1780
- if (commonArgs.schemaMode) return statusOrField.$correct;
1781
- else if (isFieldStatus(statusOrField)) {
1782
- if ("required" in statusOrField.$rules && statusOrField.$rules.required.$active) return statusOrField?.$correct;
1783
- return !statusOrField.$invalid && !statusOrField.$pending;
1784
- }
1785
- return statusOrField?.$correct;
1786
- });
1805
+ const fields = Object.entries($fields.value).reduce((acc, [key, statusOrField]) => {
1806
+ if (!isFieldStatus(statusOrField) || !statusOrField.$inactive) acc.push([key, statusOrField]);
1807
+ return acc;
1808
+ }, []);
1809
+ if (fields.length) {
1810
+ if (commonArgs.schemaMode) return fields.every(([_, statusOrField]) => statusOrField.$correct);
1811
+ return fields.every(([_, statusOrField]) => {
1812
+ if (!isFieldStatus(statusOrField)) return statusOrField?.$correct;
1813
+ const hasRequiredRule = "required" in statusOrField.$rules && statusOrField.$rules.required.$active;
1814
+ return hasRequiredRule ? statusOrField.$correct : !statusOrField.$invalid && !statusOrField.$pending;
1815
+ });
1816
+ }
1787
1817
  return false;
1788
1818
  });
1789
1819
  const $error = computed(() => {
1790
- return !!Object.entries($fields.value).length && Object.entries($fields.value).some(([_, statusOrField]) => {
1791
- return statusOrField?.$error;
1792
- });
1820
+ const fields = $fields.value;
1821
+ if (!Object.keys(fields).length) return false;
1822
+ for (const key in fields) if (fields[key]?.$error) return true;
1823
+ return false;
1793
1824
  });
1794
1825
  const $rewardEarly = computed(() => {
1795
1826
  if (unref(commonArgs.options.rewardEarly) != null) return unref(commonArgs.options.rewardEarly);
@@ -1810,29 +1841,34 @@ function createReactiveNestedStatus({ rulesDef, state, path = "", rootRules, ext
1810
1841
  });
1811
1842
  const $localPending$1 = ref(false);
1812
1843
  const $pending = computed(() => {
1813
- return $localPending$1.value || Object.entries($fields.value).some(([key, statusOrField]) => {
1814
- return statusOrField?.$pending;
1815
- });
1844
+ if ($localPending$1.value) return true;
1845
+ const fields = $fields.value;
1846
+ for (const key in fields) if (fields[key]?.$pending) return true;
1847
+ return false;
1848
+ });
1849
+ const $issues = computed(() => {
1850
+ const result = {};
1851
+ for (const key in $fields.value) result[key] = $fields.value[key]?.$issues;
1852
+ return result;
1816
1853
  });
1817
1854
  const $errors = computed(() => {
1818
- return Object.fromEntries(Object.entries($fields.value).map(([key, statusOrField]) => {
1819
- return [key, statusOrField?.$errors];
1820
- }));
1855
+ const result = {};
1856
+ for (const key in $fields.value) result[key] = $fields.value[key]?.$errors;
1857
+ return result;
1821
1858
  });
1822
1859
  const $silentErrors = computed(() => {
1823
- return Object.fromEntries(Object.entries($fields.value).map(([key, statusOrField]) => {
1824
- return [key, statusOrField?.$silentErrors];
1825
- }));
1860
+ const result = {};
1861
+ for (const key in $fields.value) result[key] = $fields.value[key]?.$silentErrors;
1862
+ return result;
1826
1863
  });
1827
1864
  const $edited = computed(() => {
1828
- return !!Object.entries($fields.value).length && Object.entries($fields.value).every(([_, statusOrField]) => {
1829
- return statusOrField?.$edited;
1830
- });
1865
+ if (!Object.keys($fields.value).length) return false;
1866
+ for (const key in $fields.value) if (!$fields.value[key]?.$edited) return false;
1867
+ return true;
1831
1868
  });
1832
1869
  const $anyEdited = computed(() => {
1833
- return Object.entries($fields.value).some(([_, statusOrField]) => {
1834
- return statusOrField?.$anyEdited;
1835
- });
1870
+ for (const key in $fields.value) if ($fields.value[key]?.$anyEdited) return true;
1871
+ return false;
1836
1872
  });
1837
1873
  const $name = computed(() => fieldName);
1838
1874
  function processShortcuts() {
@@ -1843,6 +1879,7 @@ function createReactiveNestedStatus({ rulesDef, state, path = "", rootRules, ext
1843
1879
  watchEffect(() => {
1844
1880
  result.value = value(reactive({
1845
1881
  $dirty,
1882
+ $path: path,
1846
1883
  $value: state,
1847
1884
  $silentValue,
1848
1885
  $error,
@@ -1856,7 +1893,8 @@ function createReactiveNestedStatus({ rulesDef, state, path = "", rootRules, ext
1856
1893
  $errors,
1857
1894
  $fields,
1858
1895
  $edited,
1859
- $anyEdited
1896
+ $anyEdited,
1897
+ $issues
1860
1898
  }));
1861
1899
  });
1862
1900
  return result;
@@ -1892,6 +1930,7 @@ function createReactiveNestedStatus({ rulesDef, state, path = "", rootRules, ext
1892
1930
  $correct,
1893
1931
  $error,
1894
1932
  $pending,
1933
+ $issues,
1895
1934
  $errors,
1896
1935
  $silentErrors,
1897
1936
  $ready,
@@ -1916,14 +1955,11 @@ function createReactiveNestedStatus({ rulesDef, state, path = "", rootRules, ext
1916
1955
  $unwatchSchemaErrors?.();
1917
1956
  nestedScopes = [];
1918
1957
  scopeState = {};
1919
- if ($fields.value) Object.entries($fields.value).forEach(([_, field]) => {
1920
- field.$unwatch();
1921
- });
1958
+ if ($fields.value) for (const field of Object.values($fields.value)) field.$unwatch();
1922
1959
  }
1923
1960
  function $clearExternalErrors() {
1924
- Object.entries($fields.value).forEach(([_, field]) => {
1925
- field.$clearExternalErrors();
1926
- });
1961
+ const fields = $fields.value;
1962
+ for (const field of Object.values(fields)) field.$clearExternalErrors();
1927
1963
  }
1928
1964
  function $reset(options, fromParent) {
1929
1965
  $unwatchExternalErrors?.();
@@ -1936,17 +1972,13 @@ function createReactiveNestedStatus({ rulesDef, state, path = "", rootRules, ext
1936
1972
  initialState.value = cloneDeep(newInitialState);
1937
1973
  state.value = cloneDeep(newInitialState);
1938
1974
  } else initialState.value = cloneDeep(state.value);
1939
- Object.values($fields.value).forEach((statusOrField) => {
1940
- statusOrField.$reset(options, true);
1941
- });
1975
+ for (const field of Object.values($fields.value)) field.$reset(options, true);
1942
1976
  if (options?.clearExternalErrors) $clearExternalErrors();
1943
1977
  define$WatchExternalErrors();
1944
1978
  if (!fromParent) createReactiveFieldsStatus();
1945
1979
  }
1946
1980
  function $touch(runCommit = true, withConditions = false) {
1947
- Object.values($fields.value).forEach((statusOrField) => {
1948
- statusOrField.$touch(runCommit, withConditions);
1949
- });
1981
+ for (const field of Object.values($fields.value)) field.$touch(runCommit, withConditions);
1950
1982
  }
1951
1983
  function filterNullishFields(fields) {
1952
1984
  return fields.filter(([key, value]) => {
@@ -1974,13 +2006,8 @@ function createReactiveNestedStatus({ rulesDef, state, path = "", rootRules, ext
1974
2006
  };
1975
2007
  else {
1976
2008
  const data = state.value;
1977
- const results = await Promise.allSettled(Object.values($fields.value).map((statusOrField) => {
1978
- return statusOrField.$validate();
1979
- }));
1980
- const validationResults = results.every((value) => {
1981
- if (value.status === "fulfilled") return value.value.valid === true;
1982
- else return false;
1983
- });
2009
+ const results = await Promise.allSettled(Object.values($fields.value).map((statusOrField) => statusOrField.$validate()));
2010
+ const validationResults = results.every((value) => value.status === "fulfilled" && value?.value.valid === true);
1984
2011
  return {
1985
2012
  valid: validationResults,
1986
2013
  data
@@ -1996,9 +2023,10 @@ function createReactiveNestedStatus({ rulesDef, state, path = "", rootRules, ext
1996
2023
  }
1997
2024
  }
1998
2025
  const { $shortcuts, $localPending,...restScopeState } = scopeState;
1999
- return reactive({
2026
+ const fullStatus = reactive({
2000
2027
  ...restScopeState,
2001
2028
  ...$shortcuts,
2029
+ $path: path,
2002
2030
  $fields,
2003
2031
  $reset,
2004
2032
  $touch,
@@ -2008,6 +2036,11 @@ function createReactiveNestedStatus({ rulesDef, state, path = "", rootRules, ext
2008
2036
  $clearExternalErrors,
2009
2037
  $extractDirtyFields
2010
2038
  });
2039
+ watchEffect(() => {
2040
+ for (const key in Object.keys(fullStatus).filter((key$1) => !key$1.startsWith("$"))) delete fullStatus[key];
2041
+ for (const field of Object.values($fields.value)) Object.assign(fullStatus, { [field.$name]: field });
2042
+ });
2043
+ return fullStatus;
2011
2044
  }
2012
2045
  /**
2013
2046
  * Main resolver divider, will distribute the logic depending on the type of the current value (primitive, object, array)
@@ -2065,6 +2098,7 @@ function useRootStorage({ initialState, options, scopeRules, state, customRules,
2065
2098
  shortcuts,
2066
2099
  fieldName: "root",
2067
2100
  path: "",
2101
+ cachePath: "",
2068
2102
  schemaErrors,
2069
2103
  rootSchemaErrors: schemaErrors,
2070
2104
  schemaMode,
@@ -2081,6 +2115,7 @@ function useRootStorage({ initialState, options, scopeRules, state, customRules,
2081
2115
  shortcuts,
2082
2116
  fieldName: "root",
2083
2117
  path: "",
2118
+ cachePath: "",
2084
2119
  schemaMode,
2085
2120
  schemaErrors,
2086
2121
  onValidate