@regle/core 0.7.4-beta.3 → 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) {
@@ -442,6 +442,25 @@ function randomId() {
442
442
  return uint32.toString(10);
443
443
  }
444
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
+ }
445
464
 
446
465
  // src/core/useRegle/guards/ruleDef.guards.ts
447
466
  function isNestedRulesDef(state, rules) {
@@ -474,7 +493,7 @@ function extractRulesErrors({
474
493
  silent = false
475
494
  }) {
476
495
  return Object.entries(field.$rules ?? {}).map(([_, rule]) => {
477
- if (silent) {
496
+ if (silent && !rule.$valid) {
478
497
  return rule.$message;
479
498
  } else if (!rule.$valid && field.$error && !rule.$validating) {
480
499
  return rule.$message;
@@ -874,20 +893,20 @@ function createReactiveFieldStatus({
874
893
  const $errors = computed(() => {
875
894
  return extractRulesErrors({
876
895
  field: {
896
+ $rules: $rules.value,
877
897
  $error: $error.value,
878
898
  $externalErrors: externalErrors?.value,
879
- $schemaErrors: schemaErrors?.value,
880
- $rules: $rules.value
899
+ $schemaErrors: schemaErrors?.value
881
900
  }
882
901
  });
883
902
  });
884
903
  const $silentErrors = computed(() => {
885
904
  return extractRulesErrors({
886
905
  field: {
887
- $error: true,
906
+ $rules: $rules.value,
907
+ $error: $error.value,
888
908
  $externalErrors: externalErrors?.value,
889
- $schemaErrors: schemaErrors?.value,
890
- $rules: $rules.value
909
+ $schemaErrors: schemaErrors?.value
891
910
  },
892
911
  silent: true
893
912
  });
@@ -2256,10 +2275,18 @@ function defineRegleConfig({
2256
2275
  function mergeRegles(regles, _scoped) {
2257
2276
  const scoped = _scoped == null ? false : _scoped;
2258
2277
  const $value = computed({
2259
- 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
+ },
2260
2285
  set: (value) => {
2261
- if (typeof value === "object") {
2262
- 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
+ }
2263
2290
  }
2264
2291
  }
2265
2292
  });
@@ -2272,7 +2299,8 @@ function mergeRegles(regles, _scoped) {
2272
2299
  }
2273
2300
  });
2274
2301
  const $dirty = computed(() => {
2275
- return Object.entries(regles).every(([_, regle]) => {
2302
+ const entries = Object.entries(regles);
2303
+ return !!entries.length && entries.every(([_, regle]) => {
2276
2304
  return regle?.$dirty;
2277
2305
  });
2278
2306
  });
@@ -2287,8 +2315,9 @@ function mergeRegles(regles, _scoped) {
2287
2315
  });
2288
2316
  });
2289
2317
  const $valid = computed(() => {
2290
- return Object.entries(regles).every(([_, regle]) => {
2291
- return regle?.$invalid;
2318
+ const entries = Object.entries(regles);
2319
+ return !!entries.length && entries.every(([_, regle]) => {
2320
+ return regle?.$valid;
2292
2321
  });
2293
2322
  });
2294
2323
  const $error = computed(() => {
@@ -2297,7 +2326,8 @@ function mergeRegles(regles, _scoped) {
2297
2326
  });
2298
2327
  });
2299
2328
  const $ready = computed(() => {
2300
- return Object.entries(regles).every(([_, regle]) => {
2329
+ const entries = Object.entries(regles);
2330
+ return !!entries.length && entries.every(([_, regle]) => {
2301
2331
  return regle?.$ready;
2302
2332
  });
2303
2333
  });
@@ -2307,21 +2337,34 @@ function mergeRegles(regles, _scoped) {
2307
2337
  });
2308
2338
  });
2309
2339
  const $errors = computed(() => {
2310
- return Object.fromEntries(
2311
- Object.entries(regles).map(([key, regle]) => {
2312
- return [key, regle.$errors];
2313
- })
2314
- );
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
+ }
2315
2351
  });
2316
2352
  const $silentErrors = computed(() => {
2317
- return Object.fromEntries(
2318
- Object.entries(regles).map(([key, regle]) => {
2319
- return [key, regle.$silentErrors];
2320
- })
2321
- );
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
+ }
2322
2364
  });
2323
2365
  const $edited = computed(() => {
2324
- return Object.entries(regles).every(([_, regle]) => {
2366
+ const entries = Object.entries(regles);
2367
+ return !!entries.length && entries.every(([_, regle]) => {
2325
2368
  return regle?.$edited;
2326
2369
  });
2327
2370
  });
@@ -2331,7 +2374,11 @@ function mergeRegles(regles, _scoped) {
2331
2374
  });
2332
2375
  });
2333
2376
  const $instances = computed(() => {
2334
- return regles;
2377
+ if (scoped) {
2378
+ return Object.values(regles);
2379
+ } else {
2380
+ return regles;
2381
+ }
2335
2382
  });
2336
2383
  function $reset() {
2337
2384
  Object.values(regles).forEach((regle) => {
@@ -2378,12 +2425,12 @@ function mergeRegles(regles, _scoped) {
2378
2425
  }
2379
2426
  return reactive({
2380
2427
  ...!scoped && {
2381
- $instances,
2382
- $value,
2383
- $silentValue,
2384
- $errors,
2385
- $silentErrors
2428
+ $silentValue
2386
2429
  },
2430
+ $errors,
2431
+ $silentErrors,
2432
+ $instances,
2433
+ $value,
2387
2434
  $dirty,
2388
2435
  $anyDirty,
2389
2436
  $invalid,
@@ -2401,42 +2448,112 @@ function mergeRegles(regles, _scoped) {
2401
2448
  $clearExternalErrors
2402
2449
  });
2403
2450
  }
2404
- function createUseCollectScopedValidations(instances) {
2405
- function useCollectScopedValidations() {
2406
- 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));
2407
2456
  const regle = reactive({ r$ });
2408
- watch(instances, (newInstances) => {
2409
- r$.value = mergeRegles(newInstances, true);
2410
- });
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
+ }
2411
2478
  return { r$: regle.r$ };
2412
2479
  }
2413
- return { useCollectScopedValidations };
2480
+ return { useCollectScope };
2414
2481
  }
2415
- function createUseScopedRegleComposable(customUseRegle) {
2482
+ function createUseScopedRegleComposable(instances, customUseRegle) {
2416
2483
  const scopedUseRegle = customUseRegle ?? useRegle;
2417
- const instances = ref({});
2418
2484
  const useScopedRegle = (state, rulesFactory, options) => {
2419
- const $id = randomId();
2420
- const { r$ } = scopedUseRegle(state, rulesFactory, options);
2421
- instances.value[$id] = r$;
2422
- onScopeDispose(() => {
2423
- 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();
2424
2497
  });
2425
- function $dispose() {
2426
- 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
+ }
2427
2530
  }
2428
- return { r$, $dispose };
2531
+ return { r$, dispose, register };
2429
2532
  };
2430
- return { useScopedRegle, instances };
2533
+ return { useScopedRegle };
2431
2534
  }
2432
2535
 
2433
2536
  // src/core/createScopedUseRegle/createScopedUseRegle.ts
2434
- function createScopedUseRegle(customUseRegle) {
2435
- const { instances, useScopedRegle } = createUseScopedRegleComposable(customUseRegle);
2436
- 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);
2437
2554
  return {
2438
2555
  useScopedRegle,
2439
- useCollectScopedValidations
2556
+ useCollectScope
2440
2557
  };
2441
2558
  }
2442
2559
 
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@regle/core",
3
- "version": "0.7.4-beta.3",
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",