@yiin/reactive-proxy-state 1.0.31 → 1.0.33

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
@@ -2597,6 +2597,26 @@ function deleteValue(obj, key) {
2597
2597
  else
2598
2598
  delete obj[key];
2599
2599
  }
2600
+ function validateCachedPath(root, fullPath, pathKey, cached) {
2601
+ if (fullPath.length === 0)
2602
+ return cached;
2603
+ const lastKey = fullPath[fullPath.length - 1];
2604
+ let grandparent = root;
2605
+ for (let i = 0;i < fullPath.length - 1; i++) {
2606
+ grandparent = grandparent ? getValue(grandparent, fullPath[i]) : undefined;
2607
+ if (grandparent === undefined)
2608
+ break;
2609
+ }
2610
+ if (grandparent === undefined) {
2611
+ evictDescendantsFromPathCache(root, pathKey);
2612
+ return;
2613
+ }
2614
+ const actual = getValue(grandparent, lastKey);
2615
+ if (actual === cached)
2616
+ return cached;
2617
+ evictDescendantsFromPathCache(root, pathKey);
2618
+ return;
2619
+ }
2600
2620
  var actionHandlers = {
2601
2621
  set: function(parent, key, event) {
2602
2622
  setValue(parent, key, event.newValue);
@@ -2750,6 +2770,9 @@ function updateState(root, event) {
2750
2770
  const parentPath = path.slice(0, -1);
2751
2771
  const parentPathKey = parentPath.join(".");
2752
2772
  let parent = pathCache.get(root)?.get(parentPathKey);
2773
+ if (parent !== undefined) {
2774
+ parent = validateCachedPath(root, parentPath, parentPathKey, parent);
2775
+ }
2753
2776
  if (parent === undefined) {
2754
2777
  parent = parentPath.reduce((acc, key) => acc ? getValue(acc, key) : undefined, root);
2755
2778
  if (parent !== undefined)
@@ -2769,6 +2792,9 @@ function updateState(root, event) {
2769
2792
  const targetPath = path;
2770
2793
  const targetPathKey = targetPath.join(".");
2771
2794
  let targetCollection = pathCache.get(root)?.get(targetPathKey);
2795
+ if (targetCollection !== undefined) {
2796
+ targetCollection = validateCachedPath(root, targetPath, targetPathKey, targetCollection);
2797
+ }
2772
2798
  if (targetCollection === undefined) {
2773
2799
  targetCollection = targetPath.reduce((acc, key) => acc ? getValue(acc, key) : undefined, root);
2774
2800
  if (targetCollection !== undefined)
@@ -3680,12 +3706,32 @@ function toRaw(observed) {
3680
3706
  const raw = observed && observed["__v_raw" /* RAW */];
3681
3707
  return raw ? toRaw(raw) : observed;
3682
3708
  }
3683
- function reactive(obj, emit, path = []) {
3709
+ function createAsyncEmit(emit) {
3710
+ const queue = [];
3711
+ let flushScheduled = false;
3712
+ return (event) => {
3713
+ queue.push(event);
3714
+ if (!flushScheduled) {
3715
+ flushScheduled = true;
3716
+ queueMicrotask(() => {
3717
+ flushScheduled = false;
3718
+ const batch = queue.splice(0);
3719
+ for (const queuedEvent of batch) {
3720
+ emit(queuedEvent);
3721
+ }
3722
+ });
3723
+ }
3724
+ };
3725
+ }
3726
+ function reactive(obj, emit, path = [], options) {
3684
3727
  if (obj["__v_skip" /* SKIP */]) {
3685
3728
  return obj;
3686
3729
  }
3687
3730
  if (globalSeen.has(obj))
3688
3731
  return globalSeen.get(obj);
3732
+ if (emit && path.length === 0 && options?.async) {
3733
+ emit = createAsyncEmit(emit);
3734
+ }
3689
3735
  if (emit && path.length === 0) {
3690
3736
  try {
3691
3737
  const initialEvent = {
package/dist/index.js CHANGED
@@ -2537,6 +2537,26 @@ function deleteValue(obj, key) {
2537
2537
  else
2538
2538
  delete obj[key];
2539
2539
  }
2540
+ function validateCachedPath(root, fullPath, pathKey, cached) {
2541
+ if (fullPath.length === 0)
2542
+ return cached;
2543
+ const lastKey = fullPath[fullPath.length - 1];
2544
+ let grandparent = root;
2545
+ for (let i = 0;i < fullPath.length - 1; i++) {
2546
+ grandparent = grandparent ? getValue(grandparent, fullPath[i]) : undefined;
2547
+ if (grandparent === undefined)
2548
+ break;
2549
+ }
2550
+ if (grandparent === undefined) {
2551
+ evictDescendantsFromPathCache(root, pathKey);
2552
+ return;
2553
+ }
2554
+ const actual = getValue(grandparent, lastKey);
2555
+ if (actual === cached)
2556
+ return cached;
2557
+ evictDescendantsFromPathCache(root, pathKey);
2558
+ return;
2559
+ }
2540
2560
  var actionHandlers = {
2541
2561
  set: function(parent, key, event) {
2542
2562
  setValue(parent, key, event.newValue);
@@ -2690,6 +2710,9 @@ function updateState(root, event) {
2690
2710
  const parentPath = path.slice(0, -1);
2691
2711
  const parentPathKey = parentPath.join(".");
2692
2712
  let parent = pathCache.get(root)?.get(parentPathKey);
2713
+ if (parent !== undefined) {
2714
+ parent = validateCachedPath(root, parentPath, parentPathKey, parent);
2715
+ }
2693
2716
  if (parent === undefined) {
2694
2717
  parent = parentPath.reduce((acc, key) => acc ? getValue(acc, key) : undefined, root);
2695
2718
  if (parent !== undefined)
@@ -2709,6 +2732,9 @@ function updateState(root, event) {
2709
2732
  const targetPath = path;
2710
2733
  const targetPathKey = targetPath.join(".");
2711
2734
  let targetCollection = pathCache.get(root)?.get(targetPathKey);
2735
+ if (targetCollection !== undefined) {
2736
+ targetCollection = validateCachedPath(root, targetPath, targetPathKey, targetCollection);
2737
+ }
2712
2738
  if (targetCollection === undefined) {
2713
2739
  targetCollection = targetPath.reduce((acc, key) => acc ? getValue(acc, key) : undefined, root);
2714
2740
  if (targetCollection !== undefined)
@@ -3620,12 +3646,32 @@ function toRaw(observed) {
3620
3646
  const raw = observed && observed["__v_raw" /* RAW */];
3621
3647
  return raw ? toRaw(raw) : observed;
3622
3648
  }
3623
- function reactive(obj, emit, path = []) {
3649
+ function createAsyncEmit(emit) {
3650
+ const queue = [];
3651
+ let flushScheduled = false;
3652
+ return (event) => {
3653
+ queue.push(event);
3654
+ if (!flushScheduled) {
3655
+ flushScheduled = true;
3656
+ queueMicrotask(() => {
3657
+ flushScheduled = false;
3658
+ const batch = queue.splice(0);
3659
+ for (const queuedEvent of batch) {
3660
+ emit(queuedEvent);
3661
+ }
3662
+ });
3663
+ }
3664
+ };
3665
+ }
3666
+ function reactive(obj, emit, path = [], options) {
3624
3667
  if (obj["__v_skip" /* SKIP */]) {
3625
3668
  return obj;
3626
3669
  }
3627
3670
  if (globalSeen.has(obj))
3628
3671
  return globalSeen.get(obj);
3672
+ if (emit && path.length === 0 && options?.async) {
3673
+ emit = createAsyncEmit(emit);
3674
+ }
3629
3675
  if (emit && path.length === 0) {
3630
3676
  try {
3631
3677
  const initialEvent = {
@@ -1,4 +1,4 @@
1
- import { EmitFunction, Path } from "./types";
1
+ import { EmitFunction, Path, ReactiveOptions } from "./types";
2
2
  /**
3
3
  * Checks if an object is a reactive proxy
4
4
  */
@@ -11,4 +11,4 @@ export declare function toRaw<T>(observed: T): T;
11
11
  /**
12
12
  * Create a reactive proxy for an object
13
13
  */
14
- export declare function reactive<T extends object>(obj: T, emit?: EmitFunction, path?: Path): T;
14
+ export declare function reactive<T extends object>(obj: T, emit?: EmitFunction, path?: Path, options?: ReactiveOptions): T;
package/dist/types.d.ts CHANGED
@@ -12,6 +12,10 @@ export interface StateEvent {
12
12
  oldValues?: any[];
13
13
  }
14
14
  export type EmitFunction = (event: StateEvent) => void;
15
+ export interface ReactiveOptions {
16
+ /** When true, defers emit calls to the next microtask instead of firing synchronously */
17
+ async?: boolean;
18
+ }
15
19
  import { Ref } from './ref';
16
20
  import { ComputedRef } from './computed';
17
21
  export type BaseWatchSource<T = any> = Ref<T> | ComputedRef<T> | (() => T);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yiin/reactive-proxy-state",
3
- "version": "1.0.31",
3
+ "version": "1.0.33",
4
4
  "author": "Yiin <stanislovas@yiin.lt>",
5
5
  "repository": {
6
6
  "type": "git",