@yiin/reactive-proxy-state 1.0.13 → 1.0.15

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.js CHANGED
@@ -410,6 +410,18 @@ function cleanupEffect(effect) {
410
410
  effect.dependencies.clear();
411
411
  }
412
412
  }
413
+ function runCleanupFunctions(effect) {
414
+ if (effect.cleanupFns && effect.cleanupFns.length > 0) {
415
+ effect.cleanupFns.forEach((cleanupFn) => {
416
+ try {
417
+ cleanupFn();
418
+ } catch (error) {
419
+ console.error("Error in effect cleanup function:", error);
420
+ }
421
+ });
422
+ effect.cleanupFns = [];
423
+ }
424
+ }
413
425
  function track(target, key) {
414
426
  if (!activeEffect || !activeEffect.active)
415
427
  return;
@@ -510,9 +522,16 @@ function watchEffect(effectCallback, options = {}) {
510
522
  }
511
523
  const previousEffect = activeEffect;
512
524
  try {
525
+ runCleanupFunctions(effectFn);
513
526
  cleanupEffect(effectFn);
514
527
  setActiveEffect(effectFn);
515
- return effectCallback();
528
+ const onCleanup = (cleanupFn) => {
529
+ if (!effectFn.cleanupFns) {
530
+ effectFn.cleanupFns = [];
531
+ }
532
+ effectFn.cleanupFns.push(cleanupFn);
533
+ };
534
+ return effectCallback(onCleanup);
516
535
  } finally {
517
536
  setActiveEffect(previousEffect);
518
537
  }
@@ -522,13 +541,15 @@ function watchEffect(effectCallback, options = {}) {
522
541
  dependencies: new Set,
523
542
  options,
524
543
  active: true,
525
- _rawCallback: effectCallback
544
+ _rawCallback: effectCallback,
545
+ cleanupFns: []
526
546
  };
527
547
  if (!options.lazy) {
528
548
  effectFn.run();
529
549
  }
530
550
  const stopHandle = () => {
531
551
  if (effectFn.active) {
552
+ runCleanupFunctions(effectFn);
532
553
  cleanupEffect(effectFn);
533
554
  effectFn.active = false;
534
555
  queuedEffects.delete(effectFn);
@@ -539,12 +560,12 @@ function watchEffect(effectCallback, options = {}) {
539
560
  }
540
561
 
541
562
  // src/wrap-set.ts
542
- function wrapSet(set, emit, path = [], seen = globalSeen) {
563
+ function wrapSet(set, emit, path = []) {
543
564
  const cachedProxy = wrapperCache.get(set);
544
565
  if (cachedProxy)
545
566
  return cachedProxy;
546
- if (seen.has(set))
547
- return seen.get(set);
567
+ if (globalSeen.has(set))
568
+ return globalSeen.get(set);
548
569
  const methodCache = {};
549
570
  const proxy = new Proxy(set, {
550
571
  get(target, prop, receiver) {
@@ -657,8 +678,8 @@ function wrapSet(set, emit, path = [], seen = globalSeen) {
657
678
  track(target, String(index));
658
679
  let wrappedValue = valueToWrap;
659
680
  if (valueToWrap && typeof valueToWrap === "object") {
660
- if (seen.has(valueToWrap)) {
661
- wrappedValue = seen.get(valueToWrap);
681
+ if (globalSeen.has(valueToWrap)) {
682
+ wrappedValue = globalSeen.get(valueToWrap);
662
683
  } else {
663
684
  const cachedValueProxy = wrapperCache.get(valueToWrap);
664
685
  if (cachedValueProxy) {
@@ -672,15 +693,15 @@ function wrapSet(set, emit, path = [], seen = globalSeen) {
672
693
  setPathConcat(pathKey, newPath);
673
694
  }
674
695
  if (valueToWrap instanceof Map)
675
- wrappedValue = wrapMap(valueToWrap, emit, newPath, seen);
696
+ wrappedValue = wrapMap(valueToWrap, emit, newPath);
676
697
  else if (valueToWrap instanceof Set)
677
- wrappedValue = wrapSet(valueToWrap, emit, newPath, seen);
698
+ wrappedValue = wrapSet(valueToWrap, emit, newPath);
678
699
  else if (Array.isArray(valueToWrap))
679
- wrappedValue = wrapArray(valueToWrap, emit, newPath, seen);
700
+ wrappedValue = wrapArray(valueToWrap, emit, newPath);
680
701
  else if (valueToWrap instanceof Date)
681
702
  wrappedValue = new Date(valueToWrap.getTime());
682
703
  else
683
- wrappedValue = reactive(valueToWrap, emit, newPath, seen);
704
+ wrappedValue = reactive(valueToWrap, emit, newPath);
684
705
  }
685
706
  }
686
707
  }
@@ -705,18 +726,18 @@ function wrapSet(set, emit, path = [], seen = globalSeen) {
705
726
  return value;
706
727
  }
707
728
  });
708
- seen.set(set, proxy);
729
+ globalSeen.set(set, proxy);
709
730
  wrapperCache.set(set, proxy);
710
731
  return proxy;
711
732
  }
712
733
 
713
734
  // src/wrap-map.ts
714
- function wrapMap(map, emit, path = [], seen = globalSeen) {
735
+ function wrapMap(map, emit, path = []) {
715
736
  const cachedProxy = wrapperCache.get(map);
716
737
  if (cachedProxy)
717
738
  return cachedProxy;
718
- if (seen.has(map))
719
- return seen.get(map);
739
+ if (globalSeen.has(map))
740
+ return globalSeen.get(map);
720
741
  const methodCache = {};
721
742
  const proxy = new Proxy(map, {
722
743
  get(target, prop, receiver) {
@@ -823,8 +844,8 @@ function wrapMap(map, emit, path = [], seen = globalSeen) {
823
844
  const value2 = target.get(key);
824
845
  if (!value2 || typeof value2 !== "object")
825
846
  return value2;
826
- if (seen.has(value2))
827
- return seen.get(value2);
847
+ if (globalSeen.has(value2))
848
+ return globalSeen.get(value2);
828
849
  const cachedValueProxy = wrapperCache.get(value2);
829
850
  if (cachedValueProxy)
830
851
  return cachedValueProxy;
@@ -836,14 +857,14 @@ function wrapMap(map, emit, path = [], seen = globalSeen) {
836
857
  setPathConcat(pathKey, newPath);
837
858
  }
838
859
  if (value2 instanceof Map)
839
- return wrapMap(value2, emit, newPath, seen);
860
+ return wrapMap(value2, emit, newPath);
840
861
  if (value2 instanceof Set)
841
- return wrapSet(value2, emit, newPath, seen);
862
+ return wrapSet(value2, emit, newPath);
842
863
  if (Array.isArray(value2))
843
- return wrapArray(value2, emit, newPath, seen);
864
+ return wrapArray(value2, emit, newPath);
844
865
  if (value2 instanceof Date)
845
866
  return new Date(value2.getTime());
846
- return reactive(value2, emit, newPath, seen);
867
+ return reactive(value2, emit, newPath);
847
868
  };
848
869
  return methodCache[prop];
849
870
  }
@@ -880,8 +901,8 @@ function wrapMap(map, emit, path = [], seen = globalSeen) {
880
901
  }
881
902
  let wrappedKey = keyToWrap;
882
903
  if (isEntry && keyToWrap && typeof keyToWrap === "object") {
883
- if (seen.has(keyToWrap)) {
884
- wrappedKey = seen.get(keyToWrap);
904
+ if (globalSeen.has(keyToWrap)) {
905
+ wrappedKey = globalSeen.get(keyToWrap);
885
906
  } else {
886
907
  const pathKey = path.length > 0 ? `${path.join(".")}.${String(keyToWrap)}` : String(keyToWrap);
887
908
  let keyPath = getPathConcat(pathKey);
@@ -889,13 +910,13 @@ function wrapMap(map, emit, path = [], seen = globalSeen) {
889
910
  keyPath = path.concat(String(keyToWrap));
890
911
  setPathConcat(pathKey, keyPath);
891
912
  }
892
- wrappedKey = reactive(keyToWrap, emit, keyPath, seen);
913
+ wrappedKey = reactive(keyToWrap, emit, keyPath);
893
914
  }
894
915
  }
895
916
  let wrappedValue = valueToWrap;
896
917
  if (valueToWrap && typeof valueToWrap === "object") {
897
- if (seen.has(valueToWrap)) {
898
- wrappedValue = seen.get(valueToWrap);
918
+ if (globalSeen.has(valueToWrap)) {
919
+ wrappedValue = globalSeen.get(valueToWrap);
899
920
  } else {
900
921
  const cachedValueProxy = wrapperCache.get(valueToWrap);
901
922
  if (cachedValueProxy) {
@@ -909,15 +930,15 @@ function wrapMap(map, emit, path = [], seen = globalSeen) {
909
930
  setPathConcat(pathKey, newPath);
910
931
  }
911
932
  if (valueToWrap instanceof Map)
912
- wrappedValue = wrapMap(valueToWrap, emit, newPath, seen);
933
+ wrappedValue = wrapMap(valueToWrap, emit, newPath);
913
934
  else if (valueToWrap instanceof Set)
914
- wrappedValue = wrapSet(valueToWrap, emit, newPath, seen);
935
+ wrappedValue = wrapSet(valueToWrap, emit, newPath);
915
936
  else if (Array.isArray(valueToWrap))
916
- wrappedValue = wrapArray(valueToWrap, emit, newPath, seen);
937
+ wrappedValue = wrapArray(valueToWrap, emit, newPath);
917
938
  else if (valueToWrap instanceof Date)
918
939
  wrappedValue = new Date(valueToWrap.getTime());
919
940
  else
920
- wrappedValue = reactive(valueToWrap, emit, newPath, seen);
941
+ wrappedValue = reactive(valueToWrap, emit, newPath);
921
942
  }
922
943
  }
923
944
  }
@@ -943,7 +964,7 @@ function wrapMap(map, emit, path = [], seen = globalSeen) {
943
964
  return value;
944
965
  }
945
966
  });
946
- seen.set(map, proxy);
967
+ globalSeen.set(map, proxy);
947
968
  wrapperCache.set(map, proxy);
948
969
  return proxy;
949
970
  }
@@ -952,12 +973,12 @@ function wrapMap(map, emit, path = [], seen = globalSeen) {
952
973
  function isObject2(v) {
953
974
  return v && typeof v === "object";
954
975
  }
955
- function wrapArray(arr, emit, path = [], seen = globalSeen) {
976
+ function wrapArray(arr, emit, path = []) {
956
977
  const cachedProxy = wrapperCache.get(arr);
957
978
  if (cachedProxy)
958
979
  return cachedProxy;
959
- if (seen.has(arr))
960
- return seen.get(arr);
980
+ if (globalSeen.has(arr))
981
+ return globalSeen.get(arr);
961
982
  const methodCache = {};
962
983
  const proxy = new Proxy(arr, {
963
984
  get(target, prop, receiver) {
@@ -1111,8 +1132,8 @@ function wrapArray(arr, emit, path = [], seen = globalSeen) {
1111
1132
  track(target, String(prop));
1112
1133
  if (!isObject2(value))
1113
1134
  return value;
1114
- if (seen.has(value))
1115
- return seen.get(value);
1135
+ if (globalSeen.has(value))
1136
+ return globalSeen.get(value);
1116
1137
  const cachedValueProxy = wrapperCache.get(value);
1117
1138
  if (cachedValueProxy)
1118
1139
  return cachedValueProxy;
@@ -1124,14 +1145,14 @@ function wrapArray(arr, emit, path = [], seen = globalSeen) {
1124
1145
  setPathConcat(pathKey, newPath);
1125
1146
  }
1126
1147
  if (Array.isArray(value))
1127
- return wrapArray(value, emit, newPath, seen);
1148
+ return wrapArray(value, emit, newPath);
1128
1149
  if (value instanceof Map)
1129
- return wrapMap(value, emit, newPath, seen);
1150
+ return wrapMap(value, emit, newPath);
1130
1151
  if (value instanceof Set)
1131
- return wrapSet(value, emit, newPath, seen);
1152
+ return wrapSet(value, emit, newPath);
1132
1153
  if (value instanceof Date)
1133
1154
  return new Date(value.getTime());
1134
- return reactive(value, emit, newPath, seen);
1155
+ return reactive(value, emit, newPath);
1135
1156
  }
1136
1157
  if (typeof value === "function") {
1137
1158
  return value.bind(target);
@@ -1167,7 +1188,7 @@ function wrapArray(arr, emit, path = [], seen = globalSeen) {
1167
1188
  return result;
1168
1189
  }
1169
1190
  });
1170
- seen.set(arr, proxy);
1191
+ globalSeen.set(arr, proxy);
1171
1192
  wrapperCache.set(arr, proxy);
1172
1193
  return proxy;
1173
1194
  }
@@ -1191,9 +1212,9 @@ function toRaw(observed) {
1191
1212
  const raw = observed && observed["__v_raw" /* RAW */];
1192
1213
  return raw ? toRaw(raw) : observed;
1193
1214
  }
1194
- function reactive(obj, emit, path = [], seen = globalSeen) {
1195
- if (seen.has(obj))
1196
- return seen.get(obj);
1215
+ function reactive(obj, emit, path = []) {
1216
+ if (globalSeen.has(obj))
1217
+ return globalSeen.get(obj);
1197
1218
  if (emit && path.length === 0) {
1198
1219
  try {
1199
1220
  const initialEvent = {
@@ -1207,28 +1228,28 @@ function reactive(obj, emit, path = [], seen = globalSeen) {
1207
1228
  }
1208
1229
  }
1209
1230
  if (Array.isArray(obj)) {
1210
- return wrapArray(obj, emit, path, seen);
1231
+ return wrapArray(obj, emit, path);
1211
1232
  }
1212
1233
  if (obj instanceof Map) {
1213
- return wrapMap(obj, emit, path, seen);
1234
+ return wrapMap(obj, emit, path);
1214
1235
  }
1215
1236
  if (obj instanceof Set) {
1216
- return wrapSet(obj, emit, path, seen);
1237
+ return wrapSet(obj, emit, path);
1217
1238
  }
1218
1239
  function wrapValue(val, subPath) {
1219
1240
  if (!isObject3(val))
1220
1241
  return val;
1221
- if (seen.has(val))
1222
- return seen.get(val);
1242
+ if (globalSeen.has(val))
1243
+ return globalSeen.get(val);
1223
1244
  if (Array.isArray(val))
1224
1245
  return wrapArray(val, emit, subPath);
1225
1246
  if (val instanceof Map)
1226
- return wrapMap(val, emit, subPath, seen);
1247
+ return wrapMap(val, emit, subPath);
1227
1248
  if (val instanceof Set)
1228
- return wrapSet(val, emit, subPath, seen);
1249
+ return wrapSet(val, emit, subPath);
1229
1250
  if (val instanceof Date)
1230
1251
  return new Date(val.getTime());
1231
- return reactive(val, emit, subPath, seen);
1252
+ return reactive(val, emit, subPath);
1232
1253
  }
1233
1254
  const proxy = new Proxy(obj, {
1234
1255
  get(target, prop, receiver) {
@@ -1301,7 +1322,7 @@ function reactive(obj, emit, path = [], seen = globalSeen) {
1301
1322
  return result;
1302
1323
  }
1303
1324
  });
1304
- seen.set(obj, proxy);
1325
+ globalSeen.set(obj, proxy);
1305
1326
  return proxy;
1306
1327
  }
1307
1328
  // src/watch.ts
@@ -1454,6 +1475,7 @@ export {
1454
1475
  setPathConcat,
1455
1476
  setInPathCache,
1456
1477
  setActiveEffect,
1478
+ runCleanupFunctions,
1457
1479
  ref,
1458
1480
  reactive,
1459
1481
  pathConcatCache,
@@ -1,4 +1,4 @@
1
- import { EmitFunction, Path } from './types';
1
+ import { EmitFunction, Path } 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, seen?: WeakMap<any, any>): T;
14
+ export declare function reactive<T extends object>(obj: T, emit?: EmitFunction, path?: Path): T;
@@ -1,4 +1,4 @@
1
- type EffectCallback<T = any> = () => T;
1
+ type EffectCallback<T = any> = (onCleanup?: (cleanupFn: () => void) => void) => T;
2
2
  type Scheduler = (job: () => void) => void;
3
3
  export interface WatchEffectStopHandle<T = any> {
4
4
  (): void;
@@ -11,6 +11,7 @@ export interface TrackedEffect<T = any> {
11
11
  active?: boolean;
12
12
  _rawCallback: EffectCallback<T>;
13
13
  triggerDepth?: number;
14
+ cleanupFns?: (() => void)[];
14
15
  }
15
16
  export declare let activeEffect: TrackedEffect<any> | null;
16
17
  export declare function setActiveEffect(effect: TrackedEffect<any> | null): void;
@@ -19,6 +20,11 @@ export declare function setActiveEffect(effect: TrackedEffect<any> | null): void
19
20
  * this is crucial to prevent memory leaks and unnecessary updates when an effect is stopped or re-run.
20
21
  */
21
22
  export declare function cleanupEffect(effect: TrackedEffect<any>): void;
23
+ /**
24
+ * runs all cleanup functions registered for an effect and clears them.
25
+ * called before re-running an effect or when stopping it.
26
+ */
27
+ export declare function runCleanupFunctions(effect: TrackedEffect<any>): void;
22
28
  /**
23
29
  * establishes a dependency between the currently active effect and a specific object property.
24
30
  * called by proxy getters or ref getters.
@@ -1,2 +1,2 @@
1
- import { EmitFunction, Path } from './types';
2
- export declare function wrapArray<T extends any[]>(arr: T, emit?: EmitFunction, path?: Path, seen?: WeakMap<any, any>): T;
1
+ import { EmitFunction, Path } from "./types";
2
+ export declare function wrapArray<T extends any[]>(arr: T, emit?: EmitFunction, path?: Path): T;
@@ -1,2 +1,2 @@
1
- import { EmitFunction, Path } from './types';
2
- export declare function wrapMap<K, V>(map: Map<K, V>, emit?: EmitFunction, path?: Path, seen?: WeakMap<any, any>): Map<K, V>;
1
+ import { EmitFunction, Path } from "./types";
2
+ export declare function wrapMap<K, V>(map: Map<K, V>, emit?: EmitFunction, path?: Path): Map<K, V>;
@@ -1,2 +1,2 @@
1
- import { EmitFunction, Path } from './types';
2
- export declare function wrapSet<T>(set: Set<T>, emit?: EmitFunction, path?: Path, seen?: WeakMap<any, any>): Set<T>;
1
+ import { EmitFunction, Path } from "./types";
2
+ export declare function wrapSet<T>(set: Set<T>, emit?: EmitFunction, path?: Path): Set<T>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yiin/reactive-proxy-state",
3
- "version": "1.0.13",
3
+ "version": "1.0.15",
4
4
  "author": "Yiin <stanislovas@yiin.lt>",
5
5
  "repository": {
6
6
  "type": "git",