@yiin/reactive-proxy-state 1.0.38 → 1.0.40

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
@@ -2362,6 +2362,35 @@ __export(exports_src, {
2362
2362
  module.exports = __toCommonJS(exports_src);
2363
2363
 
2364
2364
  // src/utils.ts
2365
+ function toRaw(observed) {
2366
+ let value = observed;
2367
+ while (value && value["__v_raw" /* RAW */]) {
2368
+ value = value["__v_raw" /* RAW */];
2369
+ }
2370
+ return value;
2371
+ }
2372
+ function unwrapForStore(value) {
2373
+ if (value["__v_isReactive" /* IS_REACTIVE */])
2374
+ return toRaw(value);
2375
+ if (Array.isArray(value)) {
2376
+ for (let i = 0;i < value.length; i++) {
2377
+ const child = value[i];
2378
+ if (child != null && typeof child === "object" && child["__v_isReactive" /* IS_REACTIVE */]) {
2379
+ value[i] = toRaw(child);
2380
+ }
2381
+ }
2382
+ } else if (!(value instanceof Map) && !(value instanceof Set) && !(value instanceof Date)) {
2383
+ for (const key in value) {
2384
+ if (!Object.prototype.hasOwnProperty.call(value, key))
2385
+ continue;
2386
+ const child = value[key];
2387
+ if (child != null && typeof child === "object" && child["__v_isReactive" /* IS_REACTIVE */]) {
2388
+ value[key] = toRaw(child);
2389
+ }
2390
+ }
2391
+ }
2392
+ return value;
2393
+ }
2365
2394
  var deepEqualCache = new WeakMap;
2366
2395
  var MAX_CACHE_SIZE = 1000;
2367
2396
  var pathCache = new WeakMap;
@@ -2389,6 +2418,41 @@ function resetProxyStats() {
2389
2418
  proxyStats.objects = 0;
2390
2419
  proxyStats.staleEvicted = 0;
2391
2420
  }
2421
+ function evictDeep(value) {
2422
+ if (value == null || typeof value !== "object")
2423
+ return;
2424
+ value = toRaw(value);
2425
+ if (!globalSeen.has(value))
2426
+ return;
2427
+ globalSeen.delete(value);
2428
+ wrapperCache.delete(value);
2429
+ proxyStats.staleEvicted++;
2430
+ if (Array.isArray(value)) {
2431
+ for (let i = 0;i < value.length; i++) {
2432
+ if (value[i] != null && typeof value[i] === "object") {
2433
+ evictDeep(value[i]);
2434
+ }
2435
+ }
2436
+ } else if (value instanceof Map) {
2437
+ for (const v of value.values()) {
2438
+ if (v != null && typeof v === "object")
2439
+ evictDeep(v);
2440
+ }
2441
+ } else if (value instanceof Set) {
2442
+ for (const v of value) {
2443
+ if (v != null && typeof v === "object")
2444
+ evictDeep(v);
2445
+ }
2446
+ } else {
2447
+ const keys = Object.keys(value);
2448
+ for (let i = 0;i < keys.length; i++) {
2449
+ const child = value[keys[i]];
2450
+ if (child != null && typeof child === "object") {
2451
+ evictDeep(child);
2452
+ }
2453
+ }
2454
+ }
2455
+ }
2392
2456
  function cleanupPathCache(root) {
2393
2457
  const cache = pathCache.get(root);
2394
2458
  if (cache && pathCacheSize.get(root) > MAX_CACHE_SIZE) {
@@ -3013,6 +3077,10 @@ function wrapSet(set, emit, path = []) {
3013
3077
  const methodCache = {};
3014
3078
  const proxy = new Proxy(set, {
3015
3079
  get(target, prop, receiver) {
3080
+ if (prop === "__v_raw" /* RAW */)
3081
+ return target;
3082
+ if (prop === "__v_isReactive" /* IS_REACTIVE */)
3083
+ return true;
3016
3084
  track(target, prop);
3017
3085
  if (prop === Symbol.iterator || prop === "entries" || prop === "values" || prop === "keys" || prop === "forEach") {
3018
3086
  track(target, Symbol.iterator);
@@ -3022,6 +3090,8 @@ function wrapSet(set, emit, path = []) {
3022
3090
  }
3023
3091
  if (prop === "add") {
3024
3092
  methodCache[prop] = function(value2) {
3093
+ if (value2 != null && typeof value2 === "object")
3094
+ value2 = unwrapForStore(value2);
3025
3095
  const existed = target.has(value2);
3026
3096
  const oldSize = target.size;
3027
3097
  if (!existed) {
@@ -3190,6 +3260,10 @@ function wrapMap(map, emit, path = []) {
3190
3260
  const methodCache = {};
3191
3261
  const proxy = new Proxy(map, {
3192
3262
  get(target, prop, receiver) {
3263
+ if (prop === "__v_raw" /* RAW */)
3264
+ return target;
3265
+ if (prop === "__v_isReactive" /* IS_REACTIVE */)
3266
+ return true;
3193
3267
  track(target, prop);
3194
3268
  if (prop === Symbol.iterator || prop === "entries" || prop === "values" || prop === "keys" || prop === "forEach") {
3195
3269
  track(target, Symbol.iterator);
@@ -3199,6 +3273,8 @@ function wrapMap(map, emit, path = []) {
3199
3273
  }
3200
3274
  if (prop === "set") {
3201
3275
  methodCache[prop] = function(key, value2) {
3276
+ if (value2 != null && typeof value2 === "object")
3277
+ value2 = unwrapForStore(value2);
3202
3278
  const existed = target.has(key);
3203
3279
  const oldValue = target.get(key);
3204
3280
  const oldSize = target.size;
@@ -3436,6 +3512,10 @@ function wrapArray(arr, emit, path = []) {
3436
3512
  const methodCache = {};
3437
3513
  const proxy = new Proxy(arr, {
3438
3514
  get(target, prop, receiver) {
3515
+ if (prop === "__v_raw" /* RAW */)
3516
+ return target;
3517
+ if (prop === "__v_isReactive" /* IS_REACTIVE */)
3518
+ return true;
3439
3519
  track(target, prop);
3440
3520
  if (methodCache[prop]) {
3441
3521
  return methodCache[prop];
@@ -3480,6 +3560,8 @@ function wrapArray(arr, emit, path = []) {
3480
3560
  oldValue
3481
3561
  };
3482
3562
  emit?.(event);
3563
+ if (isObject2(oldValue))
3564
+ evictDeep(oldValue);
3483
3565
  trigger(target, Symbol.iterator);
3484
3566
  if (oldLength !== newLength) {
3485
3567
  trigger(target, "length");
@@ -3503,6 +3585,8 @@ function wrapArray(arr, emit, path = []) {
3503
3585
  oldValue
3504
3586
  };
3505
3587
  emit?.(event);
3588
+ if (isObject2(oldValue))
3589
+ evictDeep(oldValue);
3506
3590
  trigger(target, Symbol.iterator);
3507
3591
  if (oldLength !== newLength) {
3508
3592
  trigger(target, "length");
@@ -3552,6 +3636,10 @@ function wrapArray(arr, emit, path = []) {
3552
3636
  oldValues: deletedItems.length > 0 ? deletedItems : undefined
3553
3637
  };
3554
3638
  emit?.(event);
3639
+ for (let i = 0;i < deletedItems.length; i++) {
3640
+ if (isObject2(deletedItems[i]))
3641
+ evictDeep(deletedItems[i]);
3642
+ }
3555
3643
  trigger(target, Symbol.iterator);
3556
3644
  if (oldLength !== newLength) {
3557
3645
  trigger(target, "length");
@@ -3687,6 +3775,8 @@ function wrapArray(arr, emit, path = []) {
3687
3775
  return value;
3688
3776
  },
3689
3777
  set(target, prop, value, receiver) {
3778
+ if (isObject2(value))
3779
+ value = unwrapForStore(value);
3690
3780
  const oldValue = target[prop];
3691
3781
  if (oldValue === value)
3692
3782
  return true;
@@ -3710,6 +3800,9 @@ function wrapArray(arr, emit, path = []) {
3710
3800
  newValue: value
3711
3801
  };
3712
3802
  emit?.(event);
3803
+ if (isObject2(oldValue) && oldValue !== value) {
3804
+ evictDeep(oldValue);
3805
+ }
3713
3806
  trigger(target, prop);
3714
3807
  }
3715
3808
  return result;
@@ -3729,10 +3822,6 @@ function isObject3(v) {
3729
3822
  function isReactive(value) {
3730
3823
  return !!(value && value["__v_isReactive" /* IS_REACTIVE */]);
3731
3824
  }
3732
- function toRaw(observed) {
3733
- const raw = observed && observed["__v_raw" /* RAW */];
3734
- return raw ? toRaw(raw) : observed;
3735
- }
3736
3825
  function createAsyncEmit(emit) {
3737
3826
  const queue = [];
3738
3827
  let flushScheduled = false;
@@ -3817,6 +3906,8 @@ function reactive(obj, emit, path = [], options) {
3817
3906
  return wrapValue(value, newPath);
3818
3907
  },
3819
3908
  set(target, prop, value, receiver) {
3909
+ if (isObject3(value))
3910
+ value = unwrapForStore(value);
3820
3911
  const oldValue = target[prop];
3821
3912
  if (oldValue === value)
3822
3913
  return true;
@@ -3841,9 +3932,7 @@ function reactive(obj, emit, path = [], options) {
3841
3932
  emit?.(event);
3842
3933
  trigger(target, prop);
3843
3934
  if (isObject3(oldValue) && oldValue !== value) {
3844
- globalSeen.delete(oldValue);
3845
- wrapperCache.delete(oldValue);
3846
- proxyStats.staleEvicted++;
3935
+ evictDeep(oldValue);
3847
3936
  }
3848
3937
  }
3849
3938
  return result;
@@ -3868,9 +3957,7 @@ function reactive(obj, emit, path = [], options) {
3868
3957
  emit?.(event);
3869
3958
  trigger(target, prop);
3870
3959
  if (isObject3(oldValue)) {
3871
- globalSeen.delete(oldValue);
3872
- wrapperCache.delete(oldValue);
3873
- proxyStats.staleEvicted++;
3960
+ evictDeep(oldValue);
3874
3961
  }
3875
3962
  }
3876
3963
  return result;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export * from './types';
2
- export { deepClone, deepEqual, getProxyStats, resetProxyStats } from './utils';
2
+ export { deepClone, deepEqual, getProxyStats, resetProxyStats, toRaw } from './utils';
3
3
  export * from './state';
4
4
  export * from './reactive';
5
5
  export * from './watch';
package/dist/index.js CHANGED
@@ -2300,6 +2300,35 @@ var require_reactivity_cjs = __commonJS((exports) => {
2300
2300
  exports.watch = watch2;
2301
2301
  });
2302
2302
  // src/utils.ts
2303
+ function toRaw(observed) {
2304
+ let value = observed;
2305
+ while (value && value["__v_raw" /* RAW */]) {
2306
+ value = value["__v_raw" /* RAW */];
2307
+ }
2308
+ return value;
2309
+ }
2310
+ function unwrapForStore(value) {
2311
+ if (value["__v_isReactive" /* IS_REACTIVE */])
2312
+ return toRaw(value);
2313
+ if (Array.isArray(value)) {
2314
+ for (let i = 0;i < value.length; i++) {
2315
+ const child = value[i];
2316
+ if (child != null && typeof child === "object" && child["__v_isReactive" /* IS_REACTIVE */]) {
2317
+ value[i] = toRaw(child);
2318
+ }
2319
+ }
2320
+ } else if (!(value instanceof Map) && !(value instanceof Set) && !(value instanceof Date)) {
2321
+ for (const key in value) {
2322
+ if (!Object.prototype.hasOwnProperty.call(value, key))
2323
+ continue;
2324
+ const child = value[key];
2325
+ if (child != null && typeof child === "object" && child["__v_isReactive" /* IS_REACTIVE */]) {
2326
+ value[key] = toRaw(child);
2327
+ }
2328
+ }
2329
+ }
2330
+ return value;
2331
+ }
2303
2332
  var deepEqualCache = new WeakMap;
2304
2333
  var MAX_CACHE_SIZE = 1000;
2305
2334
  var pathCache = new WeakMap;
@@ -2327,6 +2356,41 @@ function resetProxyStats() {
2327
2356
  proxyStats.objects = 0;
2328
2357
  proxyStats.staleEvicted = 0;
2329
2358
  }
2359
+ function evictDeep(value) {
2360
+ if (value == null || typeof value !== "object")
2361
+ return;
2362
+ value = toRaw(value);
2363
+ if (!globalSeen.has(value))
2364
+ return;
2365
+ globalSeen.delete(value);
2366
+ wrapperCache.delete(value);
2367
+ proxyStats.staleEvicted++;
2368
+ if (Array.isArray(value)) {
2369
+ for (let i = 0;i < value.length; i++) {
2370
+ if (value[i] != null && typeof value[i] === "object") {
2371
+ evictDeep(value[i]);
2372
+ }
2373
+ }
2374
+ } else if (value instanceof Map) {
2375
+ for (const v of value.values()) {
2376
+ if (v != null && typeof v === "object")
2377
+ evictDeep(v);
2378
+ }
2379
+ } else if (value instanceof Set) {
2380
+ for (const v of value) {
2381
+ if (v != null && typeof v === "object")
2382
+ evictDeep(v);
2383
+ }
2384
+ } else {
2385
+ const keys = Object.keys(value);
2386
+ for (let i = 0;i < keys.length; i++) {
2387
+ const child = value[keys[i]];
2388
+ if (child != null && typeof child === "object") {
2389
+ evictDeep(child);
2390
+ }
2391
+ }
2392
+ }
2393
+ }
2330
2394
  function cleanupPathCache(root) {
2331
2395
  const cache = pathCache.get(root);
2332
2396
  if (cache && pathCacheSize.get(root) > MAX_CACHE_SIZE) {
@@ -2951,6 +3015,10 @@ function wrapSet(set, emit, path = []) {
2951
3015
  const methodCache = {};
2952
3016
  const proxy = new Proxy(set, {
2953
3017
  get(target, prop, receiver) {
3018
+ if (prop === "__v_raw" /* RAW */)
3019
+ return target;
3020
+ if (prop === "__v_isReactive" /* IS_REACTIVE */)
3021
+ return true;
2954
3022
  track(target, prop);
2955
3023
  if (prop === Symbol.iterator || prop === "entries" || prop === "values" || prop === "keys" || prop === "forEach") {
2956
3024
  track(target, Symbol.iterator);
@@ -2960,6 +3028,8 @@ function wrapSet(set, emit, path = []) {
2960
3028
  }
2961
3029
  if (prop === "add") {
2962
3030
  methodCache[prop] = function(value2) {
3031
+ if (value2 != null && typeof value2 === "object")
3032
+ value2 = unwrapForStore(value2);
2963
3033
  const existed = target.has(value2);
2964
3034
  const oldSize = target.size;
2965
3035
  if (!existed) {
@@ -3128,6 +3198,10 @@ function wrapMap(map, emit, path = []) {
3128
3198
  const methodCache = {};
3129
3199
  const proxy = new Proxy(map, {
3130
3200
  get(target, prop, receiver) {
3201
+ if (prop === "__v_raw" /* RAW */)
3202
+ return target;
3203
+ if (prop === "__v_isReactive" /* IS_REACTIVE */)
3204
+ return true;
3131
3205
  track(target, prop);
3132
3206
  if (prop === Symbol.iterator || prop === "entries" || prop === "values" || prop === "keys" || prop === "forEach") {
3133
3207
  track(target, Symbol.iterator);
@@ -3137,6 +3211,8 @@ function wrapMap(map, emit, path = []) {
3137
3211
  }
3138
3212
  if (prop === "set") {
3139
3213
  methodCache[prop] = function(key, value2) {
3214
+ if (value2 != null && typeof value2 === "object")
3215
+ value2 = unwrapForStore(value2);
3140
3216
  const existed = target.has(key);
3141
3217
  const oldValue = target.get(key);
3142
3218
  const oldSize = target.size;
@@ -3374,6 +3450,10 @@ function wrapArray(arr, emit, path = []) {
3374
3450
  const methodCache = {};
3375
3451
  const proxy = new Proxy(arr, {
3376
3452
  get(target, prop, receiver) {
3453
+ if (prop === "__v_raw" /* RAW */)
3454
+ return target;
3455
+ if (prop === "__v_isReactive" /* IS_REACTIVE */)
3456
+ return true;
3377
3457
  track(target, prop);
3378
3458
  if (methodCache[prop]) {
3379
3459
  return methodCache[prop];
@@ -3418,6 +3498,8 @@ function wrapArray(arr, emit, path = []) {
3418
3498
  oldValue
3419
3499
  };
3420
3500
  emit?.(event);
3501
+ if (isObject2(oldValue))
3502
+ evictDeep(oldValue);
3421
3503
  trigger(target, Symbol.iterator);
3422
3504
  if (oldLength !== newLength) {
3423
3505
  trigger(target, "length");
@@ -3441,6 +3523,8 @@ function wrapArray(arr, emit, path = []) {
3441
3523
  oldValue
3442
3524
  };
3443
3525
  emit?.(event);
3526
+ if (isObject2(oldValue))
3527
+ evictDeep(oldValue);
3444
3528
  trigger(target, Symbol.iterator);
3445
3529
  if (oldLength !== newLength) {
3446
3530
  trigger(target, "length");
@@ -3490,6 +3574,10 @@ function wrapArray(arr, emit, path = []) {
3490
3574
  oldValues: deletedItems.length > 0 ? deletedItems : undefined
3491
3575
  };
3492
3576
  emit?.(event);
3577
+ for (let i = 0;i < deletedItems.length; i++) {
3578
+ if (isObject2(deletedItems[i]))
3579
+ evictDeep(deletedItems[i]);
3580
+ }
3493
3581
  trigger(target, Symbol.iterator);
3494
3582
  if (oldLength !== newLength) {
3495
3583
  trigger(target, "length");
@@ -3625,6 +3713,8 @@ function wrapArray(arr, emit, path = []) {
3625
3713
  return value;
3626
3714
  },
3627
3715
  set(target, prop, value, receiver) {
3716
+ if (isObject2(value))
3717
+ value = unwrapForStore(value);
3628
3718
  const oldValue = target[prop];
3629
3719
  if (oldValue === value)
3630
3720
  return true;
@@ -3648,6 +3738,9 @@ function wrapArray(arr, emit, path = []) {
3648
3738
  newValue: value
3649
3739
  };
3650
3740
  emit?.(event);
3741
+ if (isObject2(oldValue) && oldValue !== value) {
3742
+ evictDeep(oldValue);
3743
+ }
3651
3744
  trigger(target, prop);
3652
3745
  }
3653
3746
  return result;
@@ -3667,10 +3760,6 @@ function isObject3(v) {
3667
3760
  function isReactive(value) {
3668
3761
  return !!(value && value["__v_isReactive" /* IS_REACTIVE */]);
3669
3762
  }
3670
- function toRaw(observed) {
3671
- const raw = observed && observed["__v_raw" /* RAW */];
3672
- return raw ? toRaw(raw) : observed;
3673
- }
3674
3763
  function createAsyncEmit(emit) {
3675
3764
  const queue = [];
3676
3765
  let flushScheduled = false;
@@ -3755,6 +3844,8 @@ function reactive(obj, emit, path = [], options) {
3755
3844
  return wrapValue(value, newPath);
3756
3845
  },
3757
3846
  set(target, prop, value, receiver) {
3847
+ if (isObject3(value))
3848
+ value = unwrapForStore(value);
3758
3849
  const oldValue = target[prop];
3759
3850
  if (oldValue === value)
3760
3851
  return true;
@@ -3779,9 +3870,7 @@ function reactive(obj, emit, path = [], options) {
3779
3870
  emit?.(event);
3780
3871
  trigger(target, prop);
3781
3872
  if (isObject3(oldValue) && oldValue !== value) {
3782
- globalSeen.delete(oldValue);
3783
- wrapperCache.delete(oldValue);
3784
- proxyStats.staleEvicted++;
3873
+ evictDeep(oldValue);
3785
3874
  }
3786
3875
  }
3787
3876
  return result;
@@ -3806,9 +3895,7 @@ function reactive(obj, emit, path = [], options) {
3806
3895
  emit?.(event);
3807
3896
  trigger(target, prop);
3808
3897
  if (isObject3(oldValue)) {
3809
- globalSeen.delete(oldValue);
3810
- wrapperCache.delete(oldValue);
3811
- proxyStats.staleEvicted++;
3898
+ evictDeep(oldValue);
3812
3899
  }
3813
3900
  }
3814
3901
  return result;
@@ -3,11 +3,6 @@ import { EmitFunction, Path, ReactiveOptions } from "./types";
3
3
  * Checks if an object is a reactive proxy
4
4
  */
5
5
  export declare function isReactive(value: any): boolean;
6
- /**
7
- * Returns the raw, original object underlying a reactive proxy.
8
- * If the input is not a proxy, returns the input itself.
9
- */
10
- export declare function toRaw<T>(observed: T): T;
11
6
  /**
12
7
  * Create a reactive proxy for an object
13
8
  */
package/dist/utils.d.ts CHANGED
@@ -1,3 +1,13 @@
1
+ /**
2
+ * Returns the raw, original object underlying a reactive proxy.
3
+ * If the input is not a proxy, returns the input itself.
4
+ */
5
+ export declare function toRaw<T>(observed: T): T;
6
+ /**
7
+ * Strip proxy refs from spread results before storing in raw state.
8
+ * Prevents unbounded proxy nesting from `{ ...reactiveProxy }` patterns.
9
+ */
10
+ export declare function unwrapForStore(value: any): any;
1
11
  export declare const pathCache: WeakMap<object, Map<string, any>>;
2
12
  export declare const pathConcatCache: Map<string, any[]>;
3
13
  export declare const globalSeen: WeakMap<any, any>;
@@ -22,6 +32,12 @@ export declare function getProxyStats(): {
22
32
  staleEvicted: number;
23
33
  };
24
34
  export declare function resetProxyStats(): void;
35
+ /**
36
+ * Recursively evict an object and all its nested children from proxy caches.
37
+ * This allows GC to collect the entire old object tree when a property is
38
+ * replaced, not just the top-level value.
39
+ */
40
+ export declare function evictDeep(value: any): void;
25
41
  export declare function deepEqual(a: any, b: any, seen?: WeakMap<any, any>): boolean;
26
42
  export declare function getFromPathCache(root: object, pathKey: string): any | undefined;
27
43
  export declare function setInPathCache(root: object, pathKey: string, value: any): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yiin/reactive-proxy-state",
3
- "version": "1.0.38",
3
+ "version": "1.0.40",
4
4
  "author": "Yiin <stanislovas@yiin.lt>",
5
5
  "repository": {
6
6
  "type": "git",