@regle/core 0.0.4-beta.0 → 0.0.5

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/dist/index.cjs CHANGED
@@ -22,7 +22,8 @@ var src_exports = {};
22
22
  __export(src_exports, {
23
23
  InternalRuleType: () => InternalRuleType,
24
24
  createRule: () => createRule,
25
- defineCustomValidators: () => defineCustomValidators
25
+ defineRegleOptions: () => defineRegleOptions,
26
+ unwrapRuleParameters: () => unwrapRuleParameters
26
27
  });
27
28
  module.exports = __toCommonJS(src_exports);
28
29
 
@@ -50,6 +51,7 @@ function createReactiveParams(params) {
50
51
  // src/core/createRule/defineRuleProcessors.ts
51
52
  function defineRuleProcessors(definition, ...params) {
52
53
  const { message, validator, active, ...properties } = definition;
54
+ const isAsync = validator.constructor.name === "AsyncFunction";
53
55
  const processors = {
54
56
  message(value, ...args) {
55
57
  if (typeof definition.message === "function") {
@@ -75,6 +77,7 @@ function defineRuleProcessors(definition, ...params) {
75
77
  _active: definition.active,
76
78
  _type: definition.type,
77
79
  _patched: false,
80
+ _async: isAsync,
78
81
  _params: createReactiveParams(params)
79
82
  }
80
83
  };
@@ -86,6 +89,7 @@ function createRule(definition) {
86
89
  if (typeof definition.validator === "function") {
87
90
  let fakeParams = [];
88
91
  const staticProcessors = defineRuleProcessors(definition, ...fakeParams);
92
+ const isAsync = definition.validator.constructor.name === "AsyncFunction";
89
93
  if (definition.validator.length > 1) {
90
94
  const ruleFactory = function(...params) {
91
95
  return defineRuleProcessors(definition, ...params);
@@ -99,6 +103,7 @@ function createRule(definition) {
99
103
  ruleFactory._active = definition.active;
100
104
  ruleFactory._type = definition.type;
101
105
  ruleFactory._patched = false;
106
+ ruleFactory._async = isAsync;
102
107
  return ruleFactory;
103
108
  } else {
104
109
  return staticProcessors;
@@ -233,6 +238,9 @@ function useErrors($regle) {
233
238
  // src/core/useRegle/useStateProperties/createReactiveNestedStatus.ts
234
239
  var import_vue7 = require("vue");
235
240
 
241
+ // src/core/useRegle/useStateProperties/createReactiveCollectionStatus.ts
242
+ var import_vue6 = require("vue");
243
+
236
244
  // src/core/useRegle/useStateProperties/createReactiveFieldStatus.ts
237
245
  var import_vue5 = require("vue");
238
246
 
@@ -254,7 +262,8 @@ function createReactiveRuleStatus({
254
262
  ruleKey,
255
263
  state,
256
264
  path,
257
- storage
265
+ storage,
266
+ options
258
267
  }) {
259
268
  let scope = (0, import_vue4.effectScope)();
260
269
  let scopeState;
@@ -274,7 +283,7 @@ function createReactiveRuleStatus({
274
283
  });
275
284
  const $message = (0, import_vue4.computed)(() => {
276
285
  let message = "";
277
- const customMessageRule = customMessages[ruleKey]?.message;
286
+ const customMessageRule = customMessages ? customMessages[ruleKey]?.message : void 0;
278
287
  if (customMessageRule) {
279
288
  if (typeof customMessageRule === "function") {
280
289
  message = customMessageRule(state.value, ...$params.value);
@@ -327,7 +336,6 @@ function createReactiveRuleStatus({
327
336
  $path
328
337
  };
329
338
  });
330
- $validate();
331
339
  }
332
340
  $watch();
333
341
  const $unwatchState = (0, import_vue4.watch)(scopeState.$params, $validate, {
@@ -360,7 +368,6 @@ function createReactiveRuleStatus({
360
368
  $unwatchState();
361
369
  scope.stop();
362
370
  scope = (0, import_vue4.effectScope)();
363
- scopeState = null;
364
371
  }
365
372
  return (0, import_vue4.reactive)({
366
373
  ...scopeState,
@@ -378,12 +385,14 @@ function createReactiveFieldStatus({
378
385
  rulesDef,
379
386
  customMessages,
380
387
  path,
381
- storage
388
+ storage,
389
+ options
382
390
  }) {
383
391
  let scope = (0, import_vue5.effectScope)();
384
392
  let scopeState;
385
393
  const $dirty = (0, import_vue5.ref)(false);
386
394
  const $anyDirty = (0, import_vue5.computed)(() => $dirty.value);
395
+ const triggerPunishment = (0, import_vue5.ref)(false);
387
396
  function createReactiveRulesResult() {
388
397
  const declaredRules = rulesDef.value;
389
398
  const storeResult = storage.checkRuleDeclEntry(path, declaredRules);
@@ -400,7 +409,8 @@ function createReactiveFieldStatus({
400
409
  ruleKey,
401
410
  state,
402
411
  path,
403
- storage
412
+ storage,
413
+ options
404
414
  })
405
415
  ];
406
416
  }
@@ -410,6 +420,9 @@ function createReactiveFieldStatus({
410
420
  $watch();
411
421
  if (storeResult?.valid != null) {
412
422
  $dirty.value = storage.getDirtyState(path);
423
+ if ($dirty.value) {
424
+ $commit();
425
+ }
413
426
  }
414
427
  storage.addRuleDeclEntry(path, declaredRules);
415
428
  }
@@ -417,10 +430,14 @@ function createReactiveFieldStatus({
417
430
  storage.setDirtyEntry(path, $dirty.value);
418
431
  });
419
432
  const $unwatchState = (0, import_vue5.watch)(state, () => {
420
- if (!$dirty.value) {
421
- $dirty.value = true;
433
+ if ((0, import_vue5.unref)(options.autoDirty)) {
434
+ if (!$dirty.value) {
435
+ $dirty.value = true;
436
+ }
437
+ }
438
+ if (!(0, import_vue5.unref)(options.lazy)) {
439
+ $commit();
422
440
  }
423
- $validate();
424
441
  });
425
442
  function $unwatch() {
426
443
  if ($rules.value) {
@@ -433,9 +450,9 @@ function createReactiveFieldStatus({
433
450
  storage.setDirtyEntry(path, $dirty.value);
434
451
  }
435
452
  $unwatchState();
453
+ $unwatchValid();
436
454
  scope.stop();
437
455
  scope = (0, import_vue5.effectScope)();
438
- scopeState = null;
439
456
  }
440
457
  function $watch() {
441
458
  scopeState = scope.run(() => {
@@ -443,16 +460,30 @@ function createReactiveFieldStatus({
443
460
  return $invalid.value && !$pending.value && $dirty.value;
444
461
  });
445
462
  const $pending = (0, import_vue5.computed)(() => {
446
- return Object.entries($rules.value).some(([key, rule]) => {
447
- return rule.$pending;
448
- });
463
+ if (triggerPunishment.value || !(0, import_vue5.unref)(options.rewardEarly)) {
464
+ return Object.entries($rules.value).some(([key, ruleResult]) => {
465
+ return ruleResult.$pending;
466
+ });
467
+ }
468
+ return false;
449
469
  });
450
470
  const $invalid = (0, import_vue5.computed)(() => {
451
- return Object.entries($rules.value).some(([key, ruleResult]) => {
452
- return !ruleResult.$valid;
453
- });
471
+ if (triggerPunishment.value || !(0, import_vue5.unref)(options.rewardEarly)) {
472
+ return Object.entries($rules.value).some(([key, ruleResult]) => {
473
+ return !ruleResult.$valid;
474
+ });
475
+ }
476
+ return false;
477
+ });
478
+ const $valid = (0, import_vue5.computed)(() => {
479
+ if ((0, import_vue5.unref)(options.rewardEarly)) {
480
+ return Object.entries($rules.value).every(([key, ruleResult]) => {
481
+ return ruleResult.$valid;
482
+ });
483
+ } else {
484
+ return !$invalid.value;
485
+ }
454
486
  });
455
- const $valid = (0, import_vue5.computed)(() => !$invalid.value);
456
487
  return {
457
488
  $error,
458
489
  $pending,
@@ -463,15 +494,25 @@ function createReactiveFieldStatus({
463
494
  }
464
495
  const $rules = (0, import_vue5.ref)();
465
496
  createReactiveRulesResult();
497
+ const $unwatchValid = (0, import_vue5.watch)(scopeState.$valid, (valid) => {
498
+ if ((0, import_vue5.unref)(options.rewardEarly) && valid) {
499
+ triggerPunishment.value = false;
500
+ }
501
+ });
466
502
  function $reset() {
467
503
  $dirty.value = false;
468
504
  }
469
505
  function $touch() {
470
506
  $dirty.value = true;
471
- $validate();
507
+ }
508
+ function $commit() {
509
+ Object.entries($rules.value).map(([key, rule]) => {
510
+ return rule.$validate();
511
+ });
472
512
  }
473
513
  async function $validate() {
474
514
  try {
515
+ triggerPunishment.value = true;
475
516
  const results = await Promise.all(
476
517
  Object.entries($rules.value).map(([key, rule]) => {
477
518
  return rule.$validate();
@@ -499,14 +540,56 @@ function createReactiveFieldStatus({
499
540
  });
500
541
  }
501
542
 
543
+ // src/utils/randomId.ts
544
+ function randomId() {
545
+ const uint32 = window.crypto.getRandomValues(new Uint32Array(1))[0];
546
+ return uint32.toString(8);
547
+ }
548
+
502
549
  // src/core/useRegle/useStateProperties/createReactiveCollectionStatus.ts
503
- var import_vue6 = require("vue");
550
+ function createCollectionElement({
551
+ path,
552
+ index,
553
+ options,
554
+ storage,
555
+ value,
556
+ customMessages,
557
+ rules
558
+ }) {
559
+ const $id = randomId();
560
+ const $path = `${path}.${$id}`;
561
+ if (!value[index].$id) {
562
+ Object.defineProperties(value[index], {
563
+ $id: {
564
+ value: $id,
565
+ enumerable: false,
566
+ configurable: false,
567
+ writable: false
568
+ }
569
+ });
570
+ }
571
+ const $state = (0, import_vue6.toRefs)(value);
572
+ const $status = createReactiveChildrenStatus({
573
+ state: $state[index],
574
+ rulesDef: (0, import_vue6.toRef)(() => rules),
575
+ customMessages,
576
+ path: $path,
577
+ storage,
578
+ options
579
+ });
580
+ if ($status) {
581
+ $status.$id = value[index].$id ?? $id;
582
+ storage.addArrayStatus($status.$id, $status);
583
+ }
584
+ return $status;
585
+ }
504
586
  function createReactiveCollectionStatus({
505
587
  state,
506
588
  rulesDef,
507
589
  customMessages,
508
590
  path,
509
- storage
591
+ storage,
592
+ options
510
593
  }) {
511
594
  if (Array.isArray(state.value) && !rulesDef.value.$each) {
512
595
  return null;
@@ -523,23 +606,72 @@ function createReactiveCollectionStatus({
523
606
  rulesDef: (0, import_vue6.toRef)(() => otherFields),
524
607
  customMessages,
525
608
  path,
526
- storage
609
+ storage,
610
+ options
527
611
  });
528
612
  if (Array.isArray(state.value) && $each) {
529
613
  $eachStatus.value = state.value.map((value, index) => {
530
- const $path = `${path}.${index}`;
531
- return createReactiveChildrenStatus({
532
- state: (0, import_vue6.toRef)(() => value),
533
- rulesDef: (0, import_vue6.toRef)(() => $each),
534
- customMessages,
535
- path: $path,
536
- storage
537
- });
614
+ if (value.$id) {
615
+ const previousStatus = storage.getArrayStatus(value.$id);
616
+ if (previousStatus) {
617
+ return previousStatus;
618
+ }
619
+ } else {
620
+ return createCollectionElement({
621
+ path,
622
+ rules: $each,
623
+ value: state.value,
624
+ index,
625
+ options,
626
+ storage
627
+ });
628
+ }
538
629
  }).filter((f) => !!f);
539
630
  } else {
540
631
  $eachStatus.value = [];
541
632
  }
542
633
  }
634
+ async function updateChildrenStatus() {
635
+ const { $each } = rulesDef.value;
636
+ if (Array.isArray(state.value) && $eachStatus.value && $each) {
637
+ $unwatchState?.();
638
+ state.value.forEach((value, index) => {
639
+ if (value.$id) {
640
+ if (Array.isArray(state.value) && !state.value.find((val) => val.$id === $eachStatus.value[index].$id)) {
641
+ $eachStatus.value[index].$unwatch();
642
+ }
643
+ const previousStatus = storage.getArrayStatus(value.$id);
644
+ if (previousStatus) {
645
+ $eachStatus.value[index] = previousStatus;
646
+ } else {
647
+ $eachStatus.value[index].$unwatch();
648
+ }
649
+ } else {
650
+ const newElement = createCollectionElement({
651
+ value: state.value,
652
+ rules: $each,
653
+ customMessages,
654
+ path,
655
+ storage,
656
+ options,
657
+ index
658
+ });
659
+ if (newElement) {
660
+ $eachStatus.value[index] = newElement;
661
+ }
662
+ }
663
+ });
664
+ const deletedItems = $eachStatus.value.filter(($each2) => {
665
+ return Array.isArray(state.value) && !state.value.find((val) => val.$id === $each2.$id);
666
+ });
667
+ deletedItems.forEach((item) => {
668
+ storage.deleteArrayStatus(item.$id);
669
+ item.$unwatch();
670
+ });
671
+ $eachStatus.value.length = state.value.length;
672
+ (0, import_vue6.nextTick)($watch);
673
+ }
674
+ }
543
675
  function $unwatch() {
544
676
  if ($unwatchState) {
545
677
  $unwatchState();
@@ -554,19 +686,42 @@ function createReactiveCollectionStatus({
554
686
  }
555
687
  }
556
688
  function $watch() {
557
- $unwatchState = (0, import_vue6.watch)(
558
- state,
559
- () => {
560
- createStatus();
561
- },
562
- { deep: true, flush: "sync" }
563
- );
689
+ $unwatchState = (0, import_vue6.watch)(() => state.value.length, updateChildrenStatus, {
690
+ flush: "sync"
691
+ });
692
+ }
693
+ function $touch() {
694
+ $fieldStatus.value.$touch();
695
+ $eachStatus.value.forEach(($each) => {
696
+ $each.$touch();
697
+ });
698
+ }
699
+ function $reset() {
700
+ $fieldStatus.value.$reset();
701
+ $eachStatus.value.forEach(($each) => {
702
+ $each.$reset();
703
+ });
704
+ }
705
+ async function $validate() {
706
+ try {
707
+ const results = await Promise.all(
708
+ $eachStatus.value.map((rule) => {
709
+ return rule.$validate();
710
+ })
711
+ );
712
+ return results.every((value) => !!value);
713
+ } catch (e) {
714
+ return false;
715
+ }
564
716
  }
565
717
  return (0, import_vue6.reactive)({
566
718
  ...$fieldStatus.value,
567
719
  $each: $eachStatus,
720
+ $validate,
568
721
  $unwatch,
569
- $watch
722
+ $watch,
723
+ $touch,
724
+ $reset
570
725
  });
571
726
  }
572
727
 
@@ -577,7 +732,8 @@ function createReactiveNestedStatus({
577
732
  customMessages,
578
733
  path = "",
579
734
  rootRules,
580
- storage
735
+ storage,
736
+ options
581
737
  }) {
582
738
  let scope = (0, import_vue7.effectScope)();
583
739
  let scopeState;
@@ -595,7 +751,8 @@ function createReactiveNestedStatus({
595
751
  rulesDef: statePropRulesRef,
596
752
  customMessages,
597
753
  path: path ? `${path}.${statePropKey}` : statePropKey,
598
- storage
754
+ storage,
755
+ options
599
756
  })
600
757
  ];
601
758
  }
@@ -689,11 +846,11 @@ function createReactiveNestedStatus({
689
846
  }
690
847
  scope.stop();
691
848
  scope = (0, import_vue7.effectScope)();
692
- scopeState = null;
693
849
  }
694
850
  return (0, import_vue7.reactive)({
695
851
  ...scopeState,
696
852
  $fields,
853
+ $value: state,
697
854
  $reset,
698
855
  $touch,
699
856
  $validate,
@@ -706,7 +863,8 @@ function createReactiveChildrenStatus({
706
863
  rulesDef,
707
864
  customMessages,
708
865
  path,
709
- storage
866
+ storage,
867
+ options
710
868
  }) {
711
869
  if (isCollectionRulesDef(rulesDef)) {
712
870
  return createReactiveCollectionStatus({
@@ -714,7 +872,8 @@ function createReactiveChildrenStatus({
714
872
  rulesDef,
715
873
  customMessages,
716
874
  path,
717
- storage
875
+ storage,
876
+ options
718
877
  });
719
878
  } else if (isNestedRulesDef(state, rulesDef) && isRefObject(state)) {
720
879
  return createReactiveNestedStatus({
@@ -722,7 +881,8 @@ function createReactiveChildrenStatus({
722
881
  state,
723
882
  customMessages,
724
883
  path,
725
- storage
884
+ storage,
885
+ options
726
886
  });
727
887
  } else if (isValidatorRulesDef(rulesDef)) {
728
888
  return createReactiveFieldStatus({
@@ -730,7 +890,8 @@ function createReactiveChildrenStatus({
730
890
  rulesDef,
731
891
  customMessages,
732
892
  path,
733
- storage
893
+ storage,
894
+ options
734
895
  });
735
896
  }
736
897
  return null;
@@ -746,6 +907,7 @@ function useStorage() {
746
907
  const collectionsStorage = (0, import_vue8.shallowRef)(/* @__PURE__ */ new Map());
747
908
  const dirtyStorage = (0, import_vue8.shallowRef)(/* @__PURE__ */ new Map());
748
909
  const ruleStatusStorage = (0, import_vue8.shallowRef)(/* @__PURE__ */ new Map());
910
+ const arrayStatusStorage = (0, import_vue8.shallowRef)(/* @__PURE__ */ new Map());
749
911
  function getFieldsEntry($path) {
750
912
  const existingFields = fieldsStorage.value.get($path);
751
913
  if (existingFields) {
@@ -766,6 +928,17 @@ function useStorage() {
766
928
  return $each;
767
929
  }
768
930
  }
931
+ function addArrayStatus($id, value) {
932
+ arrayStatusStorage.value.set($id, value);
933
+ }
934
+ function getArrayStatus($id) {
935
+ return arrayStatusStorage.value.get($id);
936
+ }
937
+ function deleteArrayStatus($id) {
938
+ if ($id) {
939
+ arrayStatusStorage.value.delete($id);
940
+ }
941
+ }
769
942
  function setDirtyEntry($path, dirty) {
770
943
  dirtyStorage.value.set($path, dirty);
771
944
  }
@@ -825,20 +998,24 @@ function useStorage() {
825
998
  getDirtyState,
826
999
  trySetRuleStatusRef,
827
1000
  getFieldsEntry,
828
- getCollectionsEntry
1001
+ getCollectionsEntry,
1002
+ getArrayStatus,
1003
+ addArrayStatus,
1004
+ deleteArrayStatus
829
1005
  };
830
1006
  }
831
1007
 
832
1008
  // src/core/useRegle/useStateProperties/useStateProperties.ts
833
- function useStateProperties(scopeRules, state, customRules) {
1009
+ function useStateProperties(scopeRules, state, options, customRules) {
834
1010
  const storage = useStorage();
835
1011
  const $regle = (0, import_vue9.reactive)(
836
1012
  createReactiveNestedStatus({
837
1013
  rootRules: scopeRules,
838
1014
  scopeRules,
839
1015
  state,
840
- customMessages: customRules(),
841
- storage
1016
+ customMessages: customRules?.(),
1017
+ storage,
1018
+ options
842
1019
  })
843
1020
  );
844
1021
  const errors = useErrors($regle);
@@ -846,13 +1023,23 @@ function useStateProperties(scopeRules, state, customRules) {
846
1023
  }
847
1024
 
848
1025
  // src/core/useRegle/useRegle.ts
849
- function createUseRegleComposable(customRules) {
850
- function useRegle(state, rulesFactory) {
1026
+ function createUseRegleComposable(customRules, options) {
1027
+ const globalOptions = {
1028
+ autoDirty: options?.autoDirty ?? true,
1029
+ lazy: options?.lazy ?? false,
1030
+ rewardEarly: options?.rewardEarly ?? false
1031
+ };
1032
+ function useRegle2(state, rulesFactory, options2) {
851
1033
  const scopeRules = (0, import_vue10.isRef)(rulesFactory) ? rulesFactory : (0, import_vue10.computed)(rulesFactory);
1034
+ const resolvedOptions = {
1035
+ ...globalOptions,
1036
+ ...options2
1037
+ };
852
1038
  const initialState = (0, import_vue10.shallowRef)(structuredClone((0, import_vue10.toRaw)(state.value)));
853
1039
  const { $regle, errors } = useStateProperties(
854
1040
  scopeRules,
855
1041
  state,
1042
+ resolvedOptions,
856
1043
  customRules
857
1044
  );
858
1045
  function resetForm() {
@@ -861,7 +1048,11 @@ function createUseRegleComposable(customRules) {
861
1048
  }
862
1049
  async function validateForm() {
863
1050
  $regle.$touch();
864
- return await $regle.$validate();
1051
+ const result = await $regle.$validate();
1052
+ if (result) {
1053
+ return state.value;
1054
+ }
1055
+ return false;
865
1056
  }
866
1057
  return {
867
1058
  state,
@@ -871,19 +1062,22 @@ function createUseRegleComposable(customRules) {
871
1062
  validateForm
872
1063
  };
873
1064
  }
874
- return useRegle;
1065
+ return useRegle2;
875
1066
  }
1067
+ var useRegle = createUseRegleComposable();
876
1068
 
877
- // src/core/defineCustomValidators.ts
878
- function defineCustomValidators(customRules) {
879
- const useRegle = createUseRegleComposable(customRules);
880
- return {
881
- useRegle
882
- };
1069
+ // src/core/defineRegleOptions.ts
1070
+ function defineRegleOptions({
1071
+ rules,
1072
+ options
1073
+ }) {
1074
+ const useRegle2 = createUseRegleComposable(rules, options);
1075
+ return useRegle2;
883
1076
  }
884
1077
  // Annotate the CommonJS export names for ESM import in node:
885
1078
  0 && (module.exports = {
886
1079
  InternalRuleType,
887
1080
  createRule,
888
- defineCustomValidators
1081
+ defineRegleOptions,
1082
+ unwrapRuleParameters
889
1083
  });