@regle/core 0.7.4-beta.2 → 0.7.4

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.
@@ -1,4 +1,4 @@
1
- import { toValue, version, ref, getCurrentScope, onScopeDispose, reactive, computed, shallowRef, effectScope, isRef, toRef, unref, watch, watchEffect } from 'vue';
1
+ import { toValue, version, ref, getCurrentScope, onScopeDispose, reactive, computed, shallowRef, effectScope, isRef, toRef, unref, watch, getCurrentInstance, onMounted, watchEffect } from 'vue';
2
2
 
3
3
  // ../shared/utils/isEmpty.ts
4
4
  function isEmpty(value, considerEmptyArrayInvalid = true) {
@@ -63,7 +63,7 @@ function cloneDeep(obj) {
63
63
 
64
64
  // ../shared/utils/object.utils.ts
65
65
  function isObject(obj) {
66
- if (obj instanceof Date || obj instanceof File) {
66
+ if (obj && (obj instanceof Date || obj.constructor.name == "File" || obj.constructor.name == "FileList")) {
67
67
  return false;
68
68
  }
69
69
  return typeof obj === "object" && obj !== null && !Array.isArray(obj);
@@ -384,9 +384,6 @@ function useStorage() {
384
384
  };
385
385
  }
386
386
  function isRefObject(obj) {
387
- if (obj.value instanceof Date || obj.value instanceof File) {
388
- return false;
389
- }
390
387
  return isObject(obj.value);
391
388
  }
392
389
  function unwrapGetter(getter, value, index) {
@@ -445,6 +442,25 @@ function randomId() {
445
442
  return uint32.toString(10);
446
443
  }
447
444
  }
445
+ function tryOnScopeDispose(fn) {
446
+ if (getCurrentScope()) {
447
+ onScopeDispose(fn);
448
+ return true;
449
+ }
450
+ return false;
451
+ }
452
+ function createGlobalState(stateFactory) {
453
+ let initialized = false;
454
+ let state;
455
+ const scope = effectScope(true);
456
+ return (...args) => {
457
+ if (!initialized) {
458
+ state = scope.run(() => stateFactory(...args));
459
+ initialized = true;
460
+ }
461
+ return state;
462
+ };
463
+ }
448
464
 
449
465
  // src/core/useRegle/guards/ruleDef.guards.ts
450
466
  function isNestedRulesDef(state, rules) {
@@ -477,7 +493,7 @@ function extractRulesErrors({
477
493
  silent = false
478
494
  }) {
479
495
  return Object.entries(field.$rules ?? {}).map(([_, rule]) => {
480
- if (silent) {
496
+ if (silent && !rule.$valid) {
481
497
  return rule.$message;
482
498
  } else if (!rule.$valid && field.$error && !rule.$validating) {
483
499
  return rule.$message;
@@ -877,20 +893,20 @@ function createReactiveFieldStatus({
877
893
  const $errors = computed(() => {
878
894
  return extractRulesErrors({
879
895
  field: {
896
+ $rules: $rules.value,
880
897
  $error: $error.value,
881
898
  $externalErrors: externalErrors?.value,
882
- $schemaErrors: schemaErrors?.value,
883
- $rules: $rules.value
899
+ $schemaErrors: schemaErrors?.value
884
900
  }
885
901
  });
886
902
  });
887
903
  const $silentErrors = computed(() => {
888
904
  return extractRulesErrors({
889
905
  field: {
890
- $error: true,
906
+ $rules: $rules.value,
907
+ $error: $error.value,
891
908
  $externalErrors: externalErrors?.value,
892
- $schemaErrors: schemaErrors?.value,
893
- $rules: $rules.value
909
+ $schemaErrors: schemaErrors?.value
894
910
  },
895
911
  silent: true
896
912
  });
@@ -2259,10 +2275,18 @@ function defineRegleConfig({
2259
2275
  function mergeRegles(regles, _scoped) {
2260
2276
  const scoped = _scoped == null ? false : _scoped;
2261
2277
  const $value = computed({
2262
- get: () => Object.fromEntries(Object.entries(regles).map(([key, r]) => [key, r.$value])),
2278
+ get: () => {
2279
+ if (scoped) {
2280
+ return Object.values(regles).map((r) => r.$value);
2281
+ } else {
2282
+ return Object.fromEntries(Object.entries(regles).map(([key, r]) => [key, r.$value]));
2283
+ }
2284
+ },
2263
2285
  set: (value) => {
2264
- if (typeof value === "object") {
2265
- Object.entries(value).forEach(([key, newValue]) => regles[key].$value = newValue);
2286
+ if (!scoped) {
2287
+ if (typeof value === "object") {
2288
+ Object.entries(value).forEach(([key, newValue]) => regles[key].$value = newValue);
2289
+ }
2266
2290
  }
2267
2291
  }
2268
2292
  });
@@ -2275,7 +2299,8 @@ function mergeRegles(regles, _scoped) {
2275
2299
  }
2276
2300
  });
2277
2301
  const $dirty = computed(() => {
2278
- return Object.entries(regles).every(([_, regle]) => {
2302
+ const entries = Object.entries(regles);
2303
+ return !!entries.length && entries.every(([_, regle]) => {
2279
2304
  return regle?.$dirty;
2280
2305
  });
2281
2306
  });
@@ -2290,8 +2315,9 @@ function mergeRegles(regles, _scoped) {
2290
2315
  });
2291
2316
  });
2292
2317
  const $valid = computed(() => {
2293
- return Object.entries(regles).every(([_, regle]) => {
2294
- return regle?.$invalid;
2318
+ const entries = Object.entries(regles);
2319
+ return !!entries.length && entries.every(([_, regle]) => {
2320
+ return regle?.$valid;
2295
2321
  });
2296
2322
  });
2297
2323
  const $error = computed(() => {
@@ -2300,7 +2326,8 @@ function mergeRegles(regles, _scoped) {
2300
2326
  });
2301
2327
  });
2302
2328
  const $ready = computed(() => {
2303
- return Object.entries(regles).every(([_, regle]) => {
2329
+ const entries = Object.entries(regles);
2330
+ return !!entries.length && entries.every(([_, regle]) => {
2304
2331
  return regle?.$ready;
2305
2332
  });
2306
2333
  });
@@ -2310,21 +2337,34 @@ function mergeRegles(regles, _scoped) {
2310
2337
  });
2311
2338
  });
2312
2339
  const $errors = computed(() => {
2313
- return Object.fromEntries(
2314
- Object.entries(regles).map(([key, regle]) => {
2315
- return [key, regle.$errors];
2316
- })
2317
- );
2340
+ if (scoped) {
2341
+ return Object.entries(regles).map(([_, regle]) => {
2342
+ return regle.$errors;
2343
+ });
2344
+ } else {
2345
+ return Object.fromEntries(
2346
+ Object.entries(regles).map(([key, regle]) => {
2347
+ return [key, regle.$errors];
2348
+ })
2349
+ );
2350
+ }
2318
2351
  });
2319
2352
  const $silentErrors = computed(() => {
2320
- return Object.fromEntries(
2321
- Object.entries(regles).map(([key, regle]) => {
2322
- return [key, regle.$silentErrors];
2323
- })
2324
- );
2353
+ if (scoped) {
2354
+ return Object.entries(regles).map(([_, regle]) => {
2355
+ return regle.$silentErrors;
2356
+ });
2357
+ } else {
2358
+ return Object.fromEntries(
2359
+ Object.entries(regles).map(([key, regle]) => {
2360
+ return [key, regle.$silentErrors];
2361
+ })
2362
+ );
2363
+ }
2325
2364
  });
2326
2365
  const $edited = computed(() => {
2327
- return Object.entries(regles).every(([_, regle]) => {
2366
+ const entries = Object.entries(regles);
2367
+ return !!entries.length && entries.every(([_, regle]) => {
2328
2368
  return regle?.$edited;
2329
2369
  });
2330
2370
  });
@@ -2334,7 +2374,11 @@ function mergeRegles(regles, _scoped) {
2334
2374
  });
2335
2375
  });
2336
2376
  const $instances = computed(() => {
2337
- return regles;
2377
+ if (scoped) {
2378
+ return Object.values(regles);
2379
+ } else {
2380
+ return regles;
2381
+ }
2338
2382
  });
2339
2383
  function $reset() {
2340
2384
  Object.values(regles).forEach((regle) => {
@@ -2381,12 +2425,12 @@ function mergeRegles(regles, _scoped) {
2381
2425
  }
2382
2426
  return reactive({
2383
2427
  ...!scoped && {
2384
- $instances,
2385
- $value,
2386
- $silentValue,
2387
- $errors,
2388
- $silentErrors
2428
+ $silentValue
2389
2429
  },
2430
+ $errors,
2431
+ $silentErrors,
2432
+ $instances,
2433
+ $value,
2390
2434
  $dirty,
2391
2435
  $anyDirty,
2392
2436
  $invalid,
@@ -2404,42 +2448,112 @@ function mergeRegles(regles, _scoped) {
2404
2448
  $clearExternalErrors
2405
2449
  });
2406
2450
  }
2407
- function createUseCollectScopedValidations(instances) {
2408
- function useCollectScopedValidations() {
2409
- const r$ = ref(mergeRegles(instances.value, true));
2451
+ function createUseCollectScope(instances) {
2452
+ function useCollectScope(namespace) {
2453
+ const computedNamespace = computed(() => toValue(namespace));
2454
+ setEmptyNamespace();
2455
+ const r$ = ref(collectRegles(instances.value));
2410
2456
  const regle = reactive({ r$ });
2411
- watch(instances, (newInstances) => {
2412
- r$.value = mergeRegles(newInstances, true);
2413
- });
2457
+ function setEmptyNamespace() {
2458
+ if (computedNamespace.value && !instances.value[computedNamespace.value]) {
2459
+ instances.value[computedNamespace.value] = {};
2460
+ }
2461
+ }
2462
+ watch(computedNamespace, setEmptyNamespace);
2463
+ watch(
2464
+ instances,
2465
+ (newInstances) => {
2466
+ r$.value = collectRegles(newInstances);
2467
+ },
2468
+ { deep: true }
2469
+ );
2470
+ function collectRegles(r$Instances) {
2471
+ if (computedNamespace.value) {
2472
+ const namespaceInstances = r$Instances[computedNamespace.value] ?? {};
2473
+ return mergeRegles(namespaceInstances, true);
2474
+ } else {
2475
+ return mergeRegles(r$Instances["~~global"] ?? {}, true);
2476
+ }
2477
+ }
2414
2478
  return { r$: regle.r$ };
2415
2479
  }
2416
- return { useCollectScopedValidations };
2480
+ return { useCollectScope };
2417
2481
  }
2418
- function createUseScopedRegleComposable(customUseRegle) {
2482
+ function createUseScopedRegleComposable(instances, customUseRegle) {
2419
2483
  const scopedUseRegle = customUseRegle ?? useRegle;
2420
- const instances = ref({});
2421
2484
  const useScopedRegle = (state, rulesFactory, options) => {
2422
- const $id = randomId();
2423
- const { r$ } = scopedUseRegle(state, rulesFactory, options);
2424
- instances.value[$id] = r$;
2425
- onScopeDispose(() => {
2426
- delete instances.value[$id];
2485
+ const { namespace, ...restOptions } = options ?? {};
2486
+ const computedNamespace = computed(() => toValue(namespace));
2487
+ const $id = ref(`${Object.keys(instances.value).length + 1}-${randomId()}`);
2488
+ const instanceName = computed(() => {
2489
+ return `instance-${$id.value}`;
2490
+ });
2491
+ const { r$ } = scopedUseRegle(state, rulesFactory, restOptions);
2492
+ register();
2493
+ tryOnScopeDispose(dispose);
2494
+ watch(computedNamespace, (newName, oldName) => {
2495
+ dispose(oldName);
2496
+ register();
2427
2497
  });
2428
- function $dispose() {
2429
- delete instances.value[$id];
2498
+ if (getCurrentInstance()) {
2499
+ onMounted(() => {
2500
+ const currentInstance = getCurrentInstance();
2501
+ if (typeof window !== "undefined" && currentInstance?.proxy?.$el?.parentElement) {
2502
+ if (document.documentElement && !document.documentElement.contains(currentInstance?.proxy?.$el?.parentElement)) {
2503
+ dispose();
2504
+ }
2505
+ }
2506
+ });
2507
+ }
2508
+ function dispose(oldName) {
2509
+ const nameToClean = oldName ?? computedNamespace.value;
2510
+ if (nameToClean) {
2511
+ if (instances.value[nameToClean]) {
2512
+ delete instances.value[nameToClean][instanceName.value];
2513
+ }
2514
+ } else if (instances.value["~~global"][instanceName.value]) {
2515
+ delete instances.value["~~global"][instanceName.value];
2516
+ }
2517
+ }
2518
+ function register() {
2519
+ if (computedNamespace.value) {
2520
+ if (!instances.value[computedNamespace.value]) {
2521
+ instances.value[computedNamespace.value] = {};
2522
+ }
2523
+ instances.value[computedNamespace.value][instanceName.value] = r$;
2524
+ } else {
2525
+ if (!instances.value["~~global"]) {
2526
+ instances.value["~~global"] = {};
2527
+ }
2528
+ instances.value["~~global"][instanceName.value] = r$;
2529
+ }
2430
2530
  }
2431
- return { r$, $dispose };
2531
+ return { r$, dispose, register };
2432
2532
  };
2433
- return { useScopedRegle, instances };
2533
+ return { useScopedRegle };
2434
2534
  }
2435
2535
 
2436
2536
  // src/core/createScopedUseRegle/createScopedUseRegle.ts
2437
- function createScopedUseRegle(customUseRegle) {
2438
- const { instances, useScopedRegle } = createUseScopedRegleComposable(customUseRegle);
2439
- const { useCollectScopedValidations } = createUseCollectScopedValidations(instances);
2537
+ function createScopedUseRegle(options) {
2538
+ const useInstances = options?.customStore ? () => {
2539
+ if (options.customStore) {
2540
+ if (!options.customStore?.value["~~global"]) {
2541
+ options.customStore.value["~~global"] = {};
2542
+ } else if (options.customStore?.value) {
2543
+ options.customStore.value = { "~~global": {} };
2544
+ }
2545
+ }
2546
+ return options.customStore;
2547
+ } : createGlobalState(() => {
2548
+ const $inst = ref({ "~~global": {} });
2549
+ return $inst;
2550
+ });
2551
+ const instances = useInstances();
2552
+ const { useScopedRegle } = createUseScopedRegleComposable(instances, options?.customUseRegle);
2553
+ const { useCollectScope } = createUseCollectScope(instances);
2440
2554
  return {
2441
2555
  useScopedRegle,
2442
- useCollectScopedValidations
2556
+ useCollectScope
2443
2557
  };
2444
2558
  }
2445
2559
 
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@regle/core",
3
- "version": "0.7.4-beta.2",
3
+ "version": "0.7.4",
4
4
  "description": "Type safe form validation library for Vue 3",
5
5
  "peerDependencies": {
6
- "vue": ">=3.3.0",
7
- "pinia": ">=2.2.5"
6
+ "pinia": ">=2.2.5",
7
+ "vue": ">=3.3.0"
8
8
  },
9
9
  "peerDependenciesMeta": {
10
10
  "pinia": {
@@ -13,12 +13,12 @@
13
13
  },
14
14
  "devDependencies": {
15
15
  "@total-typescript/ts-reset": "0.6.1",
16
- "@types/node": "22.10.5",
17
- "@typescript-eslint/eslint-plugin": "8.19.1",
18
- "@typescript-eslint/parser": "8.19.1",
16
+ "@types/node": "22.10.7",
17
+ "@typescript-eslint/eslint-plugin": "8.21.0",
18
+ "@typescript-eslint/parser": "8.21.0",
19
19
  "@vue/test-utils": "2.4.6",
20
- "bumpp": "9.10.0",
21
- "changelogithub": "0.13.11",
20
+ "bumpp": "9.10.2",
21
+ "changelogithub": "13.12.1",
22
22
  "cross-env": "7.0.3",
23
23
  "eslint": "9.15.0",
24
24
  "eslint-config-prettier": "9.1.0",
@@ -26,7 +26,7 @@
26
26
  "expect-type": "1.1.0",
27
27
  "prettier": "3.3.3",
28
28
  "tsup": "8.3.5",
29
- "type-fest": "4.32.0",
29
+ "type-fest": "4.33.0",
30
30
  "typescript": "5.6.3",
31
31
  "vitest": "2.1.8",
32
32
  "vue": "3.5.13",