@regle/core 0.0.5-beta.0 → 0.0.6

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
@@ -118,8 +118,116 @@ var import_vue10 = require("vue");
118
118
  // src/core/useRegle/useStateProperties/useStateProperties.ts
119
119
  var import_vue9 = require("vue");
120
120
 
121
+ // src/core/useStorage/useStorage.ts
122
+ var import_vue2 = require("vue");
123
+ function useStorage() {
124
+ const ruleDeclStorage = (0, import_vue2.shallowRef)(/* @__PURE__ */ new Map());
125
+ const fieldsStorage = (0, import_vue2.shallowRef)(
126
+ /* @__PURE__ */ new Map()
127
+ );
128
+ const collectionsStorage = (0, import_vue2.shallowRef)(/* @__PURE__ */ new Map());
129
+ const dirtyStorage = (0, import_vue2.shallowRef)(/* @__PURE__ */ new Map());
130
+ const ruleStatusStorage = (0, import_vue2.shallowRef)(/* @__PURE__ */ new Map());
131
+ const arrayStatusStorage = (0, import_vue2.shallowRef)(/* @__PURE__ */ new Map());
132
+ function getFieldsEntry($path) {
133
+ const existingFields = fieldsStorage.value.get($path);
134
+ if (existingFields) {
135
+ return existingFields;
136
+ } else {
137
+ const $fields = (0, import_vue2.ref)({});
138
+ fieldsStorage.value.set($path, $fields);
139
+ return $fields;
140
+ }
141
+ }
142
+ function getCollectionsEntry($path) {
143
+ const existingEach = collectionsStorage.value.get($path);
144
+ if (existingEach) {
145
+ return existingEach;
146
+ } else {
147
+ const $each = (0, import_vue2.ref)([]);
148
+ collectionsStorage.value.set($path, $each);
149
+ return $each;
150
+ }
151
+ }
152
+ function addArrayStatus($id, value) {
153
+ arrayStatusStorage.value.set($id, value);
154
+ }
155
+ function getArrayStatus($id) {
156
+ return arrayStatusStorage.value.get($id);
157
+ }
158
+ function deleteArrayStatus($id) {
159
+ if ($id) {
160
+ arrayStatusStorage.value.delete($id);
161
+ }
162
+ }
163
+ function setDirtyEntry($path, dirty) {
164
+ dirtyStorage.value.set($path, dirty);
165
+ }
166
+ function getDirtyState(path) {
167
+ return dirtyStorage.value.get(path) ?? false;
168
+ }
169
+ function addRuleDeclEntry($path, options) {
170
+ ruleDeclStorage.value.set($path, options);
171
+ }
172
+ function checkRuleDeclEntry($path, newRules) {
173
+ const storedRulesDefs = ruleDeclStorage.value.get($path);
174
+ if (!storedRulesDefs)
175
+ return void 0;
176
+ const storedRules = storedRulesDefs;
177
+ const isValidCache = areRulesChanged(newRules, storedRules);
178
+ if (!isValidCache)
179
+ return { valid: false };
180
+ return { valid: true };
181
+ }
182
+ function areRulesChanged(newRules, storedRules) {
183
+ const storedRulesKeys = Object.keys(storedRules);
184
+ const newRulesKeys = Object.keys(newRules);
185
+ if (newRulesKeys.length !== storedRulesKeys.length)
186
+ return false;
187
+ const hasAllValidators = newRulesKeys.every((ruleKey) => storedRulesKeys.includes(ruleKey));
188
+ if (!hasAllValidators)
189
+ return false;
190
+ return newRulesKeys.every((ruleKey) => {
191
+ const newRuleElement = newRules[ruleKey];
192
+ const storedRuleElement = storedRules[ruleKey];
193
+ if (!storedRuleElement || !newRuleElement || typeof newRuleElement === "function" || typeof storedRuleElement === "function")
194
+ return false;
195
+ if (!newRuleElement._params)
196
+ return true;
197
+ return newRuleElement._params?.every((paramKey, index) => {
198
+ const storedParams = unwrapRuleParameters(storedRuleElement._params);
199
+ const newParams = unwrapRuleParameters(newRuleElement._params);
200
+ return storedParams?.[index] === newParams?.[index];
201
+ });
202
+ });
203
+ }
204
+ function trySetRuleStatusRef(path) {
205
+ const ruleStatus = ruleStatusStorage.value.get(path);
206
+ if (ruleStatus) {
207
+ return ruleStatus;
208
+ } else {
209
+ const $pending = (0, import_vue2.ref)(false);
210
+ const $valid = (0, import_vue2.ref)(true);
211
+ ruleStatusStorage.value.set(path, { $pending, $valid });
212
+ return { $pending, $valid };
213
+ }
214
+ }
215
+ return {
216
+ addRuleDeclEntry,
217
+ setDirtyEntry,
218
+ checkRuleDeclEntry,
219
+ getDirtyState,
220
+ trySetRuleStatusRef,
221
+ getFieldsEntry,
222
+ getCollectionsEntry,
223
+ getArrayStatus,
224
+ addArrayStatus,
225
+ deleteArrayStatus
226
+ };
227
+ }
228
+
121
229
  // src/core/useRegle/useErrors.ts
122
- var import_vue3 = require("vue");
230
+ var import_vue4 = require("vue");
123
231
 
124
232
  // src/utils/object.utils.ts
125
233
  function isObject(obj) {
@@ -153,7 +261,7 @@ function isEmpty(value) {
153
261
  }
154
262
 
155
263
  // src/utils/composables.ts
156
- var import_vue2 = require("vue");
264
+ var import_vue3 = require("vue");
157
265
 
158
266
  // src/core/useRegle/guards/ruleDef.guards.ts
159
267
  function isNestedRulesDef(state, rule) {
@@ -183,14 +291,19 @@ function isFieldStatus(rule) {
183
291
  return !!rule && "$rules" in rule;
184
292
  }
185
293
 
294
+ // src/core/useRegle/guards/rule.errors.guards.ts
295
+ function isExternalErrorCollection(value) {
296
+ return "$each" in value || "$errors" in value;
297
+ }
298
+
186
299
  // src/core/useRegle/useErrors.ts
187
- function extractRulesErrors(rules) {
300
+ function extractRulesErrors(rules, externalErrors) {
188
301
  return Object.entries(rules).map(([ruleKey, rule]) => {
189
302
  if (!rule.$valid) {
190
303
  return rule.$message;
191
304
  }
192
305
  return null;
193
- }).filter((msg) => !!msg);
306
+ }).filter((msg) => !!msg).concat(externalErrors ?? []);
194
307
  }
195
308
  function processFieldErrors(fieldStatus) {
196
309
  if (isNestedRulesStatus(fieldStatus)) {
@@ -200,8 +313,12 @@ function processFieldErrors(fieldStatus) {
200
313
  $errors: fieldStatus.$rules ? extractRulesErrors(fieldStatus.$rules) : [],
201
314
  $each: fieldStatus.$each.map(processFieldErrors)
202
315
  };
203
- } else if (isFieldStatus(fieldStatus) && fieldStatus.$error) {
204
- return extractRulesErrors(fieldStatus.$rules);
316
+ } else if (isFieldStatus(fieldStatus)) {
317
+ if (fieldStatus.$error) {
318
+ return extractRulesErrors(fieldStatus.$rules, fieldStatus.$externalErrors);
319
+ } else {
320
+ return fieldStatus.$externalErrors ?? [];
321
+ }
205
322
  }
206
323
  return [];
207
324
  }
@@ -221,31 +338,41 @@ function extractNestedErrors(fields) {
221
338
  $each: extractCollectionError(fieldStatus)
222
339
  }
223
340
  ];
224
- } else if (isFieldStatus(fieldStatus) && fieldStatus.$error) {
225
- return [fieldKey, extractRulesErrors(fieldStatus.$rules)];
341
+ } else if (isFieldStatus(fieldStatus)) {
342
+ if (fieldStatus.$error) {
343
+ return [fieldKey, extractRulesErrors(fieldStatus.$rules, fieldStatus.$externalErrors)];
344
+ } else {
345
+ return [fieldKey, fieldStatus.$externalErrors ?? []];
346
+ }
226
347
  }
227
348
  return [fieldKey, []];
228
349
  })
229
350
  );
230
351
  }
231
352
  function useErrors($regle) {
232
- const errors = (0, import_vue3.computed)(() => {
353
+ const errors = (0, import_vue4.computed)(() => {
233
354
  return extractNestedErrors($regle.$fields);
234
355
  });
235
356
  return errors;
236
357
  }
237
358
 
238
359
  // src/core/useRegle/useStateProperties/createReactiveNestedStatus.ts
239
- var import_vue7 = require("vue");
360
+ var import_vue8 = require("vue");
240
361
 
241
362
  // src/core/useRegle/useStateProperties/createReactiveCollectionStatus.ts
242
- var import_vue6 = require("vue");
363
+ var import_vue7 = require("vue");
364
+
365
+ // src/utils/randomId.ts
366
+ function randomId() {
367
+ const uint32 = window.crypto.getRandomValues(new Uint32Array(1))[0];
368
+ return uint32.toString(8);
369
+ }
243
370
 
244
371
  // src/core/useRegle/useStateProperties/createReactiveFieldStatus.ts
245
- var import_vue5 = require("vue");
372
+ var import_vue6 = require("vue");
246
373
 
247
374
  // src/core/useRegle/useStateProperties/createReactiveRuleStatus.ts
248
- var import_vue4 = require("vue");
375
+ var import_vue5 = require("vue");
249
376
 
250
377
  // src/types/rules/rule.internal.types.ts
251
378
  var InternalRuleType = /* @__PURE__ */ ((InternalRuleType2) => {
@@ -265,12 +392,12 @@ function createReactiveRuleStatus({
265
392
  storage,
266
393
  options
267
394
  }) {
268
- let scope = (0, import_vue4.effectScope)();
395
+ let scope = (0, import_vue5.effectScope)();
269
396
  let scopeState;
270
397
  const { $pending, $valid } = storage.trySetRuleStatusRef(`${path}.${ruleKey}`);
271
398
  function $watch() {
272
399
  scopeState = scope.run(() => {
273
- const $active = (0, import_vue4.computed)(() => {
400
+ const $active = (0, import_vue5.computed)(() => {
274
401
  if (isFormRuleDefinition(rule)) {
275
402
  if (typeof rule.value.active === "function") {
276
403
  return rule.value.active(state.value, ...$params.value);
@@ -281,7 +408,7 @@ function createReactiveRuleStatus({
281
408
  return true;
282
409
  }
283
410
  });
284
- const $message = (0, import_vue4.computed)(() => {
411
+ const $message = (0, import_vue5.computed)(() => {
285
412
  let message = "";
286
413
  const customMessageRule = customMessages ? customMessages[ruleKey]?.message : void 0;
287
414
  if (customMessageRule) {
@@ -306,27 +433,27 @@ function createReactiveRuleStatus({
306
433
  }
307
434
  return message;
308
435
  });
309
- const $type = (0, import_vue4.computed)(() => {
436
+ const $type = (0, import_vue5.computed)(() => {
310
437
  if (isFormRuleDefinition(rule)) {
311
438
  return Object.values(InternalRuleType).includes(rule.value.type) ? ruleKey : rule.value.type;
312
439
  } else {
313
440
  return ruleKey;
314
441
  }
315
442
  });
316
- const $validator = (0, import_vue4.computed)(() => {
443
+ const $validator = (0, import_vue5.computed)(() => {
317
444
  if (isFormRuleDefinition(rule)) {
318
445
  return rule.value.validator;
319
446
  } else {
320
447
  return rule.value;
321
448
  }
322
449
  });
323
- const $params = (0, import_vue4.computed)(() => {
450
+ const $params = (0, import_vue5.computed)(() => {
324
451
  if (typeof rule.value === "function") {
325
452
  return [];
326
453
  }
327
454
  return unwrapRuleParameters(rule.value._params ?? []);
328
455
  });
329
- const $path = (0, import_vue4.computed)(() => `${path}.${$type.value}`);
456
+ const $path = (0, import_vue5.computed)(() => `${path}.${$type.value}`);
330
457
  return {
331
458
  $active,
332
459
  $message,
@@ -338,7 +465,7 @@ function createReactiveRuleStatus({
338
465
  });
339
466
  }
340
467
  $watch();
341
- const $unwatchState = (0, import_vue4.watch)(scopeState.$params, $validate, {
468
+ const $unwatchState = (0, import_vue5.watch)(scopeState.$params, $validate, {
342
469
  deep: true
343
470
  });
344
471
  async function $validate() {
@@ -362,14 +489,16 @@ function createReactiveRuleStatus({
362
489
  ruleResult = resultOrPromise;
363
490
  }
364
491
  $valid.value = ruleResult;
492
+ if (options.$externalErrors) {
493
+ }
365
494
  return ruleResult;
366
495
  }
367
496
  function $unwatch() {
368
497
  $unwatchState();
369
498
  scope.stop();
370
- scope = (0, import_vue4.effectScope)();
499
+ scope = (0, import_vue5.effectScope)();
371
500
  }
372
- return (0, import_vue4.reactive)({
501
+ return (0, import_vue5.reactive)({
373
502
  ...scopeState,
374
503
  $pending,
375
504
  $valid,
@@ -386,20 +515,29 @@ function createReactiveFieldStatus({
386
515
  customMessages,
387
516
  path,
388
517
  storage,
389
- options
518
+ options,
519
+ externalErrors
390
520
  }) {
391
- let scope = (0, import_vue5.effectScope)();
521
+ let scope = (0, import_vue6.effectScope)();
392
522
  let scopeState;
393
- const $dirty = (0, import_vue5.ref)(false);
394
- const $anyDirty = (0, import_vue5.computed)(() => $dirty.value);
395
- const triggerPunishment = (0, import_vue5.ref)(false);
523
+ const $dirty = (0, import_vue6.ref)(false);
524
+ const $anyDirty = (0, import_vue6.computed)(() => $dirty.value);
525
+ const triggerPunishment = (0, import_vue6.ref)(false);
526
+ const $externalErrors = (0, import_vue6.ref)([]);
527
+ function collectExternalErrors() {
528
+ if (externalErrors.value) {
529
+ $externalErrors.value = externalErrors.value;
530
+ }
531
+ }
532
+ collectExternalErrors();
533
+ const $unwatchExternalErrors = (0, import_vue6.watch)(externalErrors, collectExternalErrors);
396
534
  function createReactiveRulesResult() {
397
535
  const declaredRules = rulesDef.value;
398
536
  const storeResult = storage.checkRuleDeclEntry(path, declaredRules);
399
537
  $rules.value = Object.fromEntries(
400
538
  Object.entries(declaredRules).map(([ruleKey, rule]) => {
401
539
  if (rule) {
402
- const ruleRef = (0, import_vue5.toRef)(() => rule);
540
+ const ruleRef = (0, import_vue6.toRef)(() => rule);
403
541
  return [
404
542
  ruleKey,
405
543
  createReactiveRuleStatus({
@@ -420,21 +558,26 @@ function createReactiveFieldStatus({
420
558
  $watch();
421
559
  if (storeResult?.valid != null) {
422
560
  $dirty.value = storage.getDirtyState(path);
561
+ if ($dirty.value) {
562
+ $commit();
563
+ }
423
564
  }
424
565
  storage.addRuleDeclEntry(path, declaredRules);
425
566
  }
426
- const $unwatchDirty = (0, import_vue5.watch)($dirty, () => {
567
+ const $unwatchDirty = (0, import_vue6.watch)($dirty, () => {
427
568
  storage.setDirtyEntry(path, $dirty.value);
428
569
  });
429
- const $unwatchState = (0, import_vue5.watch)(state, () => {
430
- if ((0, import_vue5.unref)(options.autoDirty)) {
570
+ const $unwatchState = (0, import_vue6.watch)(state, () => {
571
+ if ((0, import_vue6.unref)(options.autoDirty)) {
431
572
  if (!$dirty.value) {
432
573
  $dirty.value = true;
433
574
  }
434
575
  }
435
- if (!(0, import_vue5.unref)(options.lazy)) {
576
+ if (!(0, import_vue6.unref)(options.lazy)) {
436
577
  $commit();
437
578
  }
579
+ $externalErrors.value = [];
580
+ console.log($externalErrors.value);
438
581
  });
439
582
  function $unwatch() {
440
583
  if ($rules.value) {
@@ -448,32 +591,33 @@ function createReactiveFieldStatus({
448
591
  }
449
592
  $unwatchState();
450
593
  $unwatchValid();
594
+ $unwatchExternalErrors();
451
595
  scope.stop();
452
- scope = (0, import_vue5.effectScope)();
596
+ scope = (0, import_vue6.effectScope)();
453
597
  }
454
598
  function $watch() {
455
599
  scopeState = scope.run(() => {
456
- const $error = (0, import_vue5.computed)(() => {
600
+ const $error = (0, import_vue6.computed)(() => {
457
601
  return $invalid.value && !$pending.value && $dirty.value;
458
602
  });
459
- const $pending = (0, import_vue5.computed)(() => {
460
- if (triggerPunishment.value || !(0, import_vue5.unref)(options.rewardEarly)) {
603
+ const $pending = (0, import_vue6.computed)(() => {
604
+ if (triggerPunishment.value || !(0, import_vue6.unref)(options.rewardEarly)) {
461
605
  return Object.entries($rules.value).some(([key, ruleResult]) => {
462
606
  return ruleResult.$pending;
463
607
  });
464
608
  }
465
609
  return false;
466
610
  });
467
- const $invalid = (0, import_vue5.computed)(() => {
468
- if (triggerPunishment.value || !(0, import_vue5.unref)(options.rewardEarly)) {
611
+ const $invalid = (0, import_vue6.computed)(() => {
612
+ if (triggerPunishment.value || !(0, import_vue6.unref)(options.rewardEarly)) {
469
613
  return Object.entries($rules.value).some(([key, ruleResult]) => {
470
614
  return !ruleResult.$valid;
471
615
  });
472
616
  }
473
617
  return false;
474
618
  });
475
- const $valid = (0, import_vue5.computed)(() => {
476
- if ((0, import_vue5.unref)(options.rewardEarly)) {
619
+ const $valid = (0, import_vue6.computed)(() => {
620
+ if ((0, import_vue6.unref)(options.rewardEarly)) {
477
621
  return Object.entries($rules.value).every(([key, ruleResult]) => {
478
622
  return ruleResult.$valid;
479
623
  });
@@ -489,15 +633,16 @@ function createReactiveFieldStatus({
489
633
  };
490
634
  });
491
635
  }
492
- const $rules = (0, import_vue5.ref)();
636
+ const $rules = (0, import_vue6.ref)();
493
637
  createReactiveRulesResult();
494
- const $unwatchValid = (0, import_vue5.watch)(scopeState.$valid, (valid) => {
495
- if ((0, import_vue5.unref)(options.rewardEarly) && valid) {
638
+ const $unwatchValid = (0, import_vue6.watch)(scopeState.$valid, (valid) => {
639
+ if ((0, import_vue6.unref)(options.rewardEarly) && valid) {
496
640
  triggerPunishment.value = false;
497
641
  }
498
642
  });
499
643
  function $reset() {
500
644
  $dirty.value = false;
645
+ $externalErrors.value = [];
501
646
  }
502
647
  function $touch() {
503
648
  $dirty.value = true;
@@ -520,29 +665,28 @@ function createReactiveFieldStatus({
520
665
  return false;
521
666
  }
522
667
  }
523
- return (0, import_vue5.reactive)({
668
+ function $clearExternalErrors() {
669
+ $externalErrors.value = [];
670
+ }
671
+ return (0, import_vue6.reactive)({
524
672
  $dirty,
525
673
  $anyDirty,
526
674
  $invalid: scopeState.$invalid,
527
675
  $error: scopeState.$error,
528
676
  $pending: scopeState.$pending,
529
677
  $valid: scopeState.$valid,
678
+ $externalErrors,
530
679
  $value: state,
531
680
  $rules,
532
681
  $reset,
533
682
  $touch,
534
683
  $validate,
535
684
  $unwatch,
536
- $watch
685
+ $watch,
686
+ $clearExternalErrors
537
687
  });
538
688
  }
539
689
 
540
- // src/utils/randomId.ts
541
- function randomId() {
542
- const uint32 = window.crypto.getRandomValues(new Uint32Array(1))[0];
543
- return uint32.toString(8);
544
- }
545
-
546
690
  // src/core/useRegle/useStateProperties/createReactiveCollectionStatus.ts
547
691
  function createCollectionElement({
548
692
  path,
@@ -551,25 +695,31 @@ function createCollectionElement({
551
695
  storage,
552
696
  value,
553
697
  customMessages,
554
- rules
698
+ rules,
699
+ externalErrors
555
700
  }) {
556
- const $path = `${path}.${index}`;
557
701
  const $id = randomId();
702
+ const $path = `${path}.${$id}`;
558
703
  if (!value[index].$id) {
559
704
  Object.defineProperties(value[index], {
560
705
  $id: {
561
- value: $id
706
+ value: $id,
707
+ enumerable: false,
708
+ configurable: false,
709
+ writable: false
562
710
  }
563
711
  });
564
712
  }
565
- const $state = (0, import_vue6.toRefs)(value);
713
+ const $state = (0, import_vue7.toRefs)(value);
714
+ const $externalErrors = (0, import_vue7.toRefs)(externalErrors.value ?? (0, import_vue7.reactive)([void 0]));
566
715
  const $status = createReactiveChildrenStatus({
567
716
  state: $state[index],
568
- rulesDef: (0, import_vue6.toRef)(() => rules),
717
+ rulesDef: (0, import_vue7.toRef)(() => rules),
569
718
  customMessages,
570
719
  path: $path,
571
720
  storage,
572
- options
721
+ options,
722
+ externalErrors: $externalErrors?.[index]
573
723
  });
574
724
  if ($status) {
575
725
  $status.$id = value[index].$id ?? $id;
@@ -583,51 +733,88 @@ function createReactiveCollectionStatus({
583
733
  customMessages,
584
734
  path,
585
735
  storage,
586
- options
736
+ options,
737
+ externalErrors
587
738
  }) {
588
739
  if (Array.isArray(state.value) && !rulesDef.value.$each) {
589
740
  return null;
590
741
  }
591
742
  let $unwatchState = null;
592
- const $fieldStatus = (0, import_vue6.ref)({});
743
+ const $fieldStatus = (0, import_vue7.ref)({});
593
744
  const $eachStatus = storage.getCollectionsEntry(path);
594
745
  createStatus();
595
746
  $watch();
596
747
  function createStatus() {
597
748
  const { $each, ...otherFields } = rulesDef.value;
749
+ const $externalErrorsField = (0, import_vue7.toRef)(() => {
750
+ if (externalErrors.value) {
751
+ if (isExternalErrorCollection(externalErrors.value)) {
752
+ return externalErrors.value.$errors;
753
+ }
754
+ }
755
+ });
756
+ const $externalErrorsEach = (0, import_vue7.toRef)(() => {
757
+ if (externalErrors.value) {
758
+ if (isExternalErrorCollection(externalErrors.value)) {
759
+ return externalErrors.value.$each;
760
+ }
761
+ }
762
+ });
598
763
  $fieldStatus.value = createReactiveFieldStatus({
599
764
  state,
600
- rulesDef: (0, import_vue6.toRef)(() => otherFields),
765
+ rulesDef: (0, import_vue7.toRef)(() => otherFields),
601
766
  customMessages,
602
767
  path,
603
768
  storage,
604
- options
769
+ options,
770
+ externalErrors: $externalErrorsField
605
771
  });
606
772
  if (Array.isArray(state.value) && $each) {
607
773
  $eachStatus.value = state.value.map((value, index) => {
608
- return createCollectionElement({
609
- path,
610
- rules: $each,
611
- value: state.value,
612
- index,
613
- options,
614
- storage
615
- });
774
+ if (value.$id) {
775
+ const previousStatus = storage.getArrayStatus(value.$id);
776
+ if (previousStatus) {
777
+ return previousStatus;
778
+ }
779
+ } else {
780
+ return createCollectionElement({
781
+ path,
782
+ rules: $each,
783
+ value: state.value,
784
+ index,
785
+ options,
786
+ storage,
787
+ externalErrors: $externalErrorsEach
788
+ });
789
+ }
616
790
  }).filter((f) => !!f);
617
791
  } else {
618
792
  $eachStatus.value = [];
619
793
  }
620
794
  }
621
- function updateChildrenStatus() {
795
+ async function updateChildrenStatus() {
622
796
  const { $each } = rulesDef.value;
623
797
  if (Array.isArray(state.value) && $eachStatus.value && $each) {
798
+ $unwatchState?.();
624
799
  state.value.forEach((value, index) => {
625
800
  if (value.$id) {
801
+ if (Array.isArray(state.value) && !state.value.find((val) => val.$id === $eachStatus.value[index].$id)) {
802
+ $eachStatus.value[index].$unwatch();
803
+ }
626
804
  const previousStatus = storage.getArrayStatus(value.$id);
627
805
  if (previousStatus) {
628
806
  $eachStatus.value[index] = previousStatus;
807
+ } else {
808
+ $eachStatus.value[index].$unwatch();
629
809
  }
630
810
  } else {
811
+ const $externalErrorsEach = (0, import_vue7.toRef)(() => {
812
+ if (externalErrors.value) {
813
+ if ("$each" in externalErrors.value) {
814
+ return externalErrors.value.$each;
815
+ }
816
+ }
817
+ });
631
818
  const newElement = createCollectionElement({
632
819
  value: state.value,
633
820
  rules: $each,
@@ -635,19 +822,23 @@ function createReactiveCollectionStatus({
635
822
  path,
636
823
  storage,
637
824
  options,
638
- index
825
+ index,
826
+ externalErrors: $externalErrorsEach
639
827
  });
640
828
  if (newElement) {
641
829
  $eachStatus.value[index] = newElement;
642
830
  }
643
831
  }
644
832
  });
645
- }
646
- if ($eachStatus.value) {
647
833
  const deletedItems = $eachStatus.value.filter(($each2) => {
648
834
  return Array.isArray(state.value) && !state.value.find((val) => val.$id === $each2.$id);
649
835
  });
650
- deletedItems.forEach((item) => item.$unwatch());
836
+ deletedItems.forEach((item) => {
837
+ storage.deleteArrayStatus(item.$id);
838
+ item.$unwatch();
839
+ });
840
+ $eachStatus.value.length = state.value.length;
841
+ (0, import_vue7.nextTick)($watch);
651
842
  }
652
843
  }
653
844
  function $unwatch() {
@@ -664,13 +855,9 @@ function createReactiveCollectionStatus({
664
855
  }
665
856
  }
666
857
  function $watch() {
667
- $unwatchState = (0, import_vue6.watch)(
668
- state,
669
- () => {
670
- updateChildrenStatus();
671
- },
672
- { deep: true, flush: "sync" }
673
- );
858
+ $unwatchState = (0, import_vue7.watch)(() => state.value.length, updateChildrenStatus, {
859
+ flush: "sync"
860
+ });
674
861
  }
675
862
  function $touch() {
676
863
  $fieldStatus.value.$touch();
@@ -696,7 +883,7 @@ function createReactiveCollectionStatus({
696
883
  return false;
697
884
  }
698
885
  }
699
- return (0, import_vue6.reactive)({
886
+ return (0, import_vue7.reactive)({
700
887
  ...$fieldStatus.value,
701
888
  $each: $eachStatus,
702
889
  $validate,
@@ -715,17 +902,19 @@ function createReactiveNestedStatus({
715
902
  path = "",
716
903
  rootRules,
717
904
  storage,
718
- options
905
+ options,
906
+ externalErrors
719
907
  }) {
720
- let scope = (0, import_vue7.effectScope)();
908
+ let scope = (0, import_vue8.effectScope)();
721
909
  let scopeState;
722
910
  let $unwatchFields;
723
911
  function createReactiveFieldsStatus() {
724
912
  $fields.value = Object.fromEntries(
725
913
  Object.entries(scopeRules.value).map(([statePropKey, statePropRules]) => {
726
914
  if (statePropRules) {
727
- const stateRef = (0, import_vue7.toRef)(state.value, statePropKey);
728
- const statePropRulesRef = (0, import_vue7.toRef)(() => statePropRules);
915
+ const stateRef = (0, import_vue8.toRef)(state.value, statePropKey);
916
+ const statePropRulesRef = (0, import_vue8.toRef)(() => statePropRules);
917
+ const $externalErrors = (0, import_vue8.toRef)(() => externalErrors.value?.[statePropKey]);
729
918
  return [
730
919
  statePropKey,
731
920
  createReactiveChildrenStatus({
@@ -734,7 +923,8 @@ function createReactiveNestedStatus({
734
923
  customMessages,
735
924
  path: path ? `${path}.${statePropKey}` : statePropKey,
736
925
  storage,
737
- options
926
+ options,
927
+ externalErrors: $externalErrors
738
928
  })
739
929
  ];
740
930
  }
@@ -771,7 +961,7 @@ function createReactiveNestedStatus({
771
961
  }
772
962
  function $watch() {
773
963
  if (rootRules) {
774
- $unwatchFields = (0, import_vue7.watch)(
964
+ $unwatchFields = (0, import_vue8.watch)(
775
965
  rootRules,
776
966
  () => {
777
967
  $unwatch();
@@ -781,28 +971,28 @@ function createReactiveNestedStatus({
781
971
  );
782
972
  }
783
973
  scopeState = scope.run(() => {
784
- const $dirty = (0, import_vue7.computed)(() => {
974
+ const $dirty = (0, import_vue8.computed)(() => {
785
975
  return Object.entries($fields.value).every(([key, statusOrField]) => {
786
976
  return statusOrField.$dirty;
787
977
  });
788
978
  });
789
- const $anyDirty = (0, import_vue7.computed)(() => {
979
+ const $anyDirty = (0, import_vue8.computed)(() => {
790
980
  return Object.entries($fields.value).some(([key, statusOrField]) => {
791
981
  return statusOrField.$dirty;
792
982
  });
793
983
  });
794
- const $invalid = (0, import_vue7.computed)(() => {
984
+ const $invalid = (0, import_vue8.computed)(() => {
795
985
  return Object.entries($fields.value).some(([key, statusOrField]) => {
796
986
  return statusOrField.$invalid;
797
987
  });
798
988
  });
799
- const $valid = (0, import_vue7.computed)(() => !$invalid.value);
800
- const $error = (0, import_vue7.computed)(() => {
989
+ const $valid = (0, import_vue8.computed)(() => !$invalid.value);
990
+ const $error = (0, import_vue8.computed)(() => {
801
991
  return Object.entries($fields.value).some(([key, statusOrField]) => {
802
992
  return statusOrField.$error;
803
993
  });
804
994
  });
805
- const $pending = (0, import_vue7.computed)(() => {
995
+ const $pending = (0, import_vue8.computed)(() => {
806
996
  return Object.entries($fields.value).some(([key, statusOrField]) => {
807
997
  return statusOrField.$pending;
808
998
  });
@@ -827,9 +1017,14 @@ function createReactiveNestedStatus({
827
1017
  $unwatchFields();
828
1018
  }
829
1019
  scope.stop();
830
- scope = (0, import_vue7.effectScope)();
1020
+ scope = (0, import_vue8.effectScope)();
831
1021
  }
832
- return (0, import_vue7.reactive)({
1022
+ function $clearExternalErrors() {
1023
+ Object.entries($fields.value).forEach(([_, field]) => {
1024
+ field.$clearExternalErrors();
1025
+ });
1026
+ }
1027
+ return (0, import_vue8.reactive)({
833
1028
  ...scopeState,
834
1029
  $fields,
835
1030
  $value: state,
@@ -837,7 +1032,8 @@ function createReactiveNestedStatus({
837
1032
  $touch,
838
1033
  $validate,
839
1034
  $unwatch,
840
- $watch
1035
+ $watch,
1036
+ $clearExternalErrors
841
1037
  });
842
1038
  }
843
1039
  function createReactiveChildrenStatus({
@@ -846,7 +1042,8 @@ function createReactiveChildrenStatus({
846
1042
  customMessages,
847
1043
  path,
848
1044
  storage,
849
- options
1045
+ options,
1046
+ externalErrors
850
1047
  }) {
851
1048
  if (isCollectionRulesDef(rulesDef)) {
852
1049
  return createReactiveCollectionStatus({
@@ -855,7 +1052,8 @@ function createReactiveChildrenStatus({
855
1052
  customMessages,
856
1053
  path,
857
1054
  storage,
858
- options
1055
+ options,
1056
+ externalErrors
859
1057
  });
860
1058
  } else if (isNestedRulesDef(state, rulesDef) && isRefObject(state)) {
861
1059
  return createReactiveNestedStatus({
@@ -864,7 +1062,8 @@ function createReactiveChildrenStatus({
864
1062
  customMessages,
865
1063
  path,
866
1064
  storage,
867
- options
1065
+ options,
1066
+ externalErrors
868
1067
  });
869
1068
  } else if (isValidatorRulesDef(rulesDef)) {
870
1069
  return createReactiveFieldStatus({
@@ -873,117 +1072,17 @@ function createReactiveChildrenStatus({
873
1072
  customMessages,
874
1073
  path,
875
1074
  storage,
876
- options
1075
+ options,
1076
+ externalErrors
877
1077
  });
878
1078
  }
879
1079
  return null;
880
1080
  }
881
1081
 
882
- // src/core/useStorage/useStorage.ts
883
- var import_vue8 = require("vue");
884
- function useStorage() {
885
- const ruleDeclStorage = (0, import_vue8.shallowRef)(/* @__PURE__ */ new Map());
886
- const fieldsStorage = (0, import_vue8.shallowRef)(
887
- /* @__PURE__ */ new Map()
888
- );
889
- const collectionsStorage = (0, import_vue8.shallowRef)(/* @__PURE__ */ new Map());
890
- const dirtyStorage = (0, import_vue8.shallowRef)(/* @__PURE__ */ new Map());
891
- const ruleStatusStorage = (0, import_vue8.shallowRef)(/* @__PURE__ */ new Map());
892
- const arrayStatusStorage = (0, import_vue8.shallowRef)(/* @__PURE__ */ new Map());
893
- function getFieldsEntry($path) {
894
- const existingFields = fieldsStorage.value.get($path);
895
- if (existingFields) {
896
- return existingFields;
897
- } else {
898
- const $fields = (0, import_vue8.ref)({});
899
- fieldsStorage.value.set($path, $fields);
900
- return $fields;
901
- }
902
- }
903
- function getCollectionsEntry($path) {
904
- const existingEach = collectionsStorage.value.get($path);
905
- if (existingEach) {
906
- return existingEach;
907
- } else {
908
- const $each = (0, import_vue8.ref)([]);
909
- collectionsStorage.value.set($path, $each);
910
- return $each;
911
- }
912
- }
913
- function addArrayStatus($id, value) {
914
- arrayStatusStorage.value.set($id, value);
915
- }
916
- function getArrayStatus($id) {
917
- return arrayStatusStorage.value.get($id);
918
- }
919
- function setDirtyEntry($path, dirty) {
920
- dirtyStorage.value.set($path, dirty);
921
- }
922
- function getDirtyState(path) {
923
- return dirtyStorage.value.get(path) ?? false;
924
- }
925
- function addRuleDeclEntry($path, options) {
926
- ruleDeclStorage.value.set($path, options);
927
- }
928
- function checkRuleDeclEntry($path, newRules) {
929
- const storedRulesDefs = ruleDeclStorage.value.get($path);
930
- if (!storedRulesDefs)
931
- return void 0;
932
- const storedRules = storedRulesDefs;
933
- const isValidCache = areRulesChanged(newRules, storedRules);
934
- if (!isValidCache)
935
- return { valid: false };
936
- return { valid: true };
937
- }
938
- function areRulesChanged(newRules, storedRules) {
939
- const storedRulesKeys = Object.keys(storedRules);
940
- const newRulesKeys = Object.keys(newRules);
941
- if (newRulesKeys.length !== storedRulesKeys.length)
942
- return false;
943
- const hasAllValidators = newRulesKeys.every((ruleKey) => storedRulesKeys.includes(ruleKey));
944
- if (!hasAllValidators)
945
- return false;
946
- return newRulesKeys.every((ruleKey) => {
947
- const newRuleElement = newRules[ruleKey];
948
- const storedRuleElement = storedRules[ruleKey];
949
- if (!storedRuleElement || !newRuleElement || typeof newRuleElement === "function" || typeof storedRuleElement === "function")
950
- return false;
951
- if (!newRuleElement._params)
952
- return true;
953
- return newRuleElement._params?.every((paramKey, index) => {
954
- const storedParams = unwrapRuleParameters(storedRuleElement._params);
955
- const newParams = unwrapRuleParameters(newRuleElement._params);
956
- return storedParams?.[index] === newParams?.[index];
957
- });
958
- });
959
- }
960
- function trySetRuleStatusRef(path) {
961
- const ruleStatus = ruleStatusStorage.value.get(path);
962
- if (ruleStatus) {
963
- return ruleStatus;
964
- } else {
965
- const $pending = (0, import_vue8.ref)(false);
966
- const $valid = (0, import_vue8.ref)(true);
967
- ruleStatusStorage.value.set(path, { $pending, $valid });
968
- return { $pending, $valid };
969
- }
970
- }
971
- return {
972
- addRuleDeclEntry,
973
- setDirtyEntry,
974
- checkRuleDeclEntry,
975
- getDirtyState,
976
- trySetRuleStatusRef,
977
- getFieldsEntry,
978
- getCollectionsEntry,
979
- getArrayStatus,
980
- addArrayStatus
981
- };
982
- }
983
-
984
1082
  // src/core/useRegle/useStateProperties/useStateProperties.ts
985
1083
  function useStateProperties(scopeRules, state, options, customRules) {
986
1084
  const storage = useStorage();
1085
+ const externalErrors = (0, import_vue9.computed)(() => (0, import_vue9.unref)(options.$externalErrors));
987
1086
  const $regle = (0, import_vue9.reactive)(
988
1087
  createReactiveNestedStatus({
989
1088
  rootRules: scopeRules,
@@ -991,7 +1090,8 @@ function useStateProperties(scopeRules, state, options, customRules) {
991
1090
  state,
992
1091
  customMessages: customRules?.(),
993
1092
  storage,
994
- options
1093
+ options,
1094
+ externalErrors
995
1095
  })
996
1096
  );
997
1097
  const errors = useErrors($regle);
@@ -1011,10 +1111,11 @@ function createUseRegleComposable(customRules, options) {
1011
1111
  ...globalOptions,
1012
1112
  ...options2
1013
1113
  };
1014
- const initialState = (0, import_vue10.shallowRef)(structuredClone((0, import_vue10.toRaw)(state.value)));
1114
+ const processedState = (0, import_vue10.ref)(state);
1115
+ const initialState = (0, import_vue10.shallowRef)(structuredClone((0, import_vue10.toRaw)(processedState.value)));
1015
1116
  const { $regle, errors } = useStateProperties(
1016
1117
  scopeRules,
1017
- state,
1118
+ processedState,
1018
1119
  resolvedOptions,
1019
1120
  customRules
1020
1121
  );
@@ -1022,6 +1123,12 @@ function createUseRegleComposable(customRules, options) {
1022
1123
  state.value = (0, import_vue10.toRaw)(initialState.value);
1023
1124
  $regle.$reset();
1024
1125
  }
1126
+ const $valid = (0, import_vue10.computed)(() => {
1127
+ return $regle.$valid && $regle.$dirty && !$regle.$pending;
1128
+ });
1129
+ const $invalid = (0, import_vue10.computed)(() => {
1130
+ return $regle.$invalid && $regle.$dirty || $regle.$pending;
1131
+ });
1025
1132
  async function validateForm() {
1026
1133
  $regle.$touch();
1027
1134
  const result = await $regle.$validate();
@@ -1031,11 +1138,13 @@ function createUseRegleComposable(customRules, options) {
1031
1138
  return false;
1032
1139
  }
1033
1140
  return {
1034
- state,
1141
+ $state: state,
1035
1142
  $regle,
1036
- errors,
1143
+ $errors: errors,
1037
1144
  resetForm,
1038
- validateForm
1145
+ validateForm,
1146
+ $valid,
1147
+ $invalid
1039
1148
  };
1040
1149
  }
1041
1150
  return useRegle2;