@yiin/reactive-proxy-state 1.0.14 → 1.0.16

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;
@@ -501,18 +513,20 @@ function trigger(target, key) {
501
513
  function watchEffect(effectCallback, options = {}) {
502
514
  const run = () => {
503
515
  if (!effectFn.active) {
504
- try {
505
- return effectCallback();
506
- } catch (e) {
507
- console.error("error in stopped watchEffect callback:", e);
508
- return;
509
- }
516
+ throw new Error("Trying to run a stopped effect");
510
517
  }
511
518
  const previousEffect = activeEffect;
512
519
  try {
520
+ runCleanupFunctions(effectFn);
513
521
  cleanupEffect(effectFn);
514
522
  setActiveEffect(effectFn);
515
- return effectCallback();
523
+ const onCleanup = (cleanupFn) => {
524
+ if (!effectFn.cleanupFns) {
525
+ effectFn.cleanupFns = [];
526
+ }
527
+ effectFn.cleanupFns.push(cleanupFn);
528
+ };
529
+ return effectCallback(onCleanup);
516
530
  } finally {
517
531
  setActiveEffect(previousEffect);
518
532
  }
@@ -522,13 +536,15 @@ function watchEffect(effectCallback, options = {}) {
522
536
  dependencies: new Set,
523
537
  options,
524
538
  active: true,
525
- _rawCallback: effectCallback
539
+ _rawCallback: effectCallback,
540
+ cleanupFns: []
526
541
  };
527
542
  if (!options.lazy) {
528
543
  effectFn.run();
529
544
  }
530
545
  const stopHandle = () => {
531
546
  if (effectFn.active) {
547
+ runCleanupFunctions(effectFn);
532
548
  cleanupEffect(effectFn);
533
549
  effectFn.active = false;
534
550
  queuedEffects.delete(effectFn);
@@ -1454,6 +1470,7 @@ export {
1454
1470
  setPathConcat,
1455
1471
  setInPathCache,
1456
1472
  setActiveEffect,
1473
+ runCleanupFunctions,
1457
1474
  ref,
1458
1475
  reactive,
1459
1476
  pathConcatCache,
@@ -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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yiin/reactive-proxy-state",
3
- "version": "1.0.14",
3
+ "version": "1.0.16",
4
4
  "author": "Yiin <stanislovas@yiin.lt>",
5
5
  "repository": {
6
6
  "type": "git",