@@ -272,6 +272,7 @@ class Syncache<T> {
272272 retry: retry ?? defaultRetry,
273273 cancel: cancel,
274274 tags: null ,
275+ skipNotify: true , // Meta strategy handles its own notifications
275276 );
276277 }
277278
@@ -1399,6 +1400,11 @@ class Syncache<T> {
13991400 ///
14001401 /// This unified method handles all policy variants,
14011402 /// delegating fetch/wrap operations to the strategy.
1403+ ///
1404+ /// When [skipNotify] is true, the method will not call [_notify] after
1405+ /// cache hits or fetches. This is used by [getWithMeta] since the meta
1406+ /// strategy handles value notifications internally via [_notifyValue] ,
1407+ /// and [watchWithMeta] handles meta notifications via manual emission.
14021408 Future <R > _executePolicy <R >({
14031409 required String key,
14041410 required Policy policy,
@@ -1407,14 +1413,15 @@ class Syncache<T> {
14071413 required RetryConfig retry,
14081414 required CancellationToken ? cancel,
14091415 required List <String >? tags,
1416+ bool skipNotify = false ,
14101417 }) async {
14111418 switch (policy) {
14121419 case Policy .cacheOnly:
14131420 final cached = await store.read (key);
14141421 if (cached == null ) {
14151422 throw CacheMissException (key);
14161423 }
1417- _notify (key, isFromCache: true );
1424+ if ( ! skipNotify) _notify (key, isFromCache: true );
14181425 return strategy.wrapCached (cached, isStale: cached.meta.isExpired);
14191426
14201427 case Policy .networkOnly:
@@ -1426,7 +1433,7 @@ class Syncache<T> {
14261433 cancel,
14271434 tags,
14281435 );
1429- _notify (key, isFromCache: false );
1436+ if ( ! skipNotify) _notify (key, isFromCache: false );
14301437 return result;
14311438
14321439 case Policy .refresh:
@@ -1439,21 +1446,21 @@ class Syncache<T> {
14391446 cancel,
14401447 tags,
14411448 );
1442- _notify (key, isFromCache: false );
1449+ if ( ! skipNotify) _notify (key, isFromCache: false );
14431450 return result;
14441451 }
14451452 final cached = await store.read (key);
14461453 if (cached == null ) {
14471454 throw CacheMissException (key);
14481455 }
1449- _notify (key, isFromCache: true );
1456+ if ( ! skipNotify) _notify (key, isFromCache: true );
14501457 return strategy.wrapCached (cached, isStale: cached.meta.isExpired);
14511458
14521459 case Policy .offlineFirst:
14531460 final cached = await store.read (key);
14541461 if (cached != null && ! cached.meta.isExpired) {
14551462 _notifyObservers ((o) => o.onCacheHit (key));
1456- _notify (key, isFromCache: true );
1463+ if ( ! skipNotify) _notify (key, isFromCache: true );
14571464 return strategy.wrapCached (cached, isStale: false );
14581465 }
14591466
@@ -1469,7 +1476,7 @@ class Syncache<T> {
14691476 cancel,
14701477 tags,
14711478 );
1472- _notify (key, isFromCache: false );
1479+ if ( ! skipNotify) _notify (key, isFromCache: false );
14731480 return result;
14741481 } on CancelledException {
14751482 rethrow ;
@@ -1478,7 +1485,7 @@ class Syncache<T> {
14781485 throw CacheMissException (key);
14791486 }
14801487 if (cached != null ) {
1481- _notify (key, isFromCache: true );
1488+ if ( ! skipNotify) _notify (key, isFromCache: true );
14821489 return strategy.wrapCached (cached,
14831490 isStale: cached.meta.isExpired);
14841491 }
@@ -1487,7 +1494,7 @@ class Syncache<T> {
14871494 }
14881495
14891496 if (cached != null ) {
1490- _notify (key, isFromCache: true );
1497+ if ( ! skipNotify) _notify (key, isFromCache: true );
14911498 return strategy.wrapCached (cached, isStale: cached.meta.isExpired);
14921499 }
14931500
@@ -1502,6 +1509,7 @@ class Syncache<T> {
15021509 cancel: cancel,
15031510 tags: tags,
15041511 refreshOnlyIfExpired: true ,
1512+ skipNotify: skipNotify,
15051513 );
15061514
15071515 case Policy .cacheAndRefresh:
@@ -1513,6 +1521,7 @@ class Syncache<T> {
15131521 cancel: cancel,
15141522 tags: tags,
15151523 refreshOnlyIfExpired: false ,
1524+ skipNotify: skipNotify,
15161525 );
15171526 }
15181527 }
@@ -1530,6 +1539,7 @@ class Syncache<T> {
15301539 required CancellationToken ? cancel,
15311540 required List <String >? tags,
15321541 required bool refreshOnlyIfExpired,
1542+ bool skipNotify = false ,
15331543 }) async {
15341544 final cached = await store.read (key);
15351545
@@ -1542,13 +1552,14 @@ class Syncache<T> {
15421552 if (shouldRefresh) {
15431553 strategy
15441554 .backgroundRefresh (_fetchEngine, key, ttl, retry, tags)
1545- .then ((_) => _notify (key, isFromCache: false ))
1546- .catchError ((Object e, StackTrace st) {
1555+ .then ((_) {
1556+ _notify (key, isFromCache: false );
1557+ }).catchError ((Object e, StackTrace st) {
15471558 _notifyObservers ((o) => o.onFetchError (key, e, st));
15481559 });
15491560 }
15501561
1551- _notify (key, isFromCache: true );
1562+ if ( ! skipNotify) _notify (key, isFromCache: true );
15521563 return strategy.wrapCached (cached, isStale: cached.meta.isExpired);
15531564 }
15541565
@@ -1563,7 +1574,7 @@ class Syncache<T> {
15631574 cancel,
15641575 tags,
15651576 );
1566- _notify (key, isFromCache: false );
1577+ if ( ! skipNotify) _notify (key, isFromCache: false );
15671578 return result;
15681579 }
15691580
0 commit comments