@adaptic/utils 0.0.1008 → 0.0.1009

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.mjs CHANGED
@@ -63616,6 +63616,15 @@ class StampedeProtectedCache {
63616
63616
  allowStale: true,
63617
63617
  updateAgeOnGet: false,
63618
63618
  updateAgeOnHas: false,
63619
+ // LRU discard visibility for the onEvent observability hook. lru-cache
63620
+ // invokes dispose for every removal; only capacity discards ("evict")
63621
+ // are reported as evictions so deliberate delete()/invalidate() calls
63622
+ // do not inflate the eviction signal.
63623
+ dispose: (_value, key, reason) => {
63624
+ if (reason === "evict") {
63625
+ this.emitEvent("eviction", key);
63626
+ }
63627
+ },
63619
63628
  });
63620
63629
  this.options.logger.info("StampedeProtectedCache initialized", {
63621
63630
  maxSize: this.options.maxSize,
@@ -63683,6 +63692,7 @@ class StampedeProtectedCache {
63683
63692
  if (now < jitteredExpiresAt) {
63684
63693
  // Fresh hit
63685
63694
  this.stats.hits++;
63695
+ this.emitEvent("hit", key);
63686
63696
  this.options.logger.debug("Cache hit (fresh)", {
63687
63697
  key,
63688
63698
  age: now - cached.createdAt,
@@ -63694,6 +63704,7 @@ class StampedeProtectedCache {
63694
63704
  if (now < staleExpiresAt && !cached.isRefreshing) {
63695
63705
  // Serve stale and trigger background refresh
63696
63706
  this.stats.staleHits++;
63707
+ this.emitEvent("stale_hit", key);
63697
63708
  this.options.logger.debug("Cache hit (stale-while-revalidate)", {
63698
63709
  key,
63699
63710
  age: now - cached.createdAt,
@@ -63707,6 +63718,7 @@ class StampedeProtectedCache {
63707
63718
  }
63708
63719
  // Cache miss or expired - need to load
63709
63720
  this.stats.misses++;
63721
+ this.emitEvent("miss", key);
63710
63722
  this.options.logger.debug("Cache miss", { key, hadCached: !!cached });
63711
63723
  return this.loadWithCoalescing(key, loader, effectiveTtl);
63712
63724
  }
@@ -63784,6 +63796,25 @@ class StampedeProtectedCache {
63784
63796
  * cache.delete(`positions:${accountId}`);
63785
63797
  * ```
63786
63798
  */
63799
+ /**
63800
+ * Fire the {@link StampedeProtectedCacheOptions.onEvent} hook, never
63801
+ * letting an observer failure propagate into the cache path.
63802
+ */
63803
+ emitEvent(event, key) {
63804
+ const hook = this.options.onEvent;
63805
+ if (!hook)
63806
+ return;
63807
+ try {
63808
+ hook(event, key);
63809
+ }
63810
+ catch (err) {
63811
+ this.options.logger.warn("cache onEvent observer threw — ignored", {
63812
+ event,
63813
+ key,
63814
+ error: err instanceof Error ? err.message : String(err),
63815
+ });
63816
+ }
63817
+ }
63787
63818
  delete(key) {
63788
63819
  const deleted = this.cache.delete(key);
63789
63820
  if (deleted) {
@@ -63916,6 +63947,7 @@ class StampedeProtectedCache {
63916
63947
  const existingPromise = this.pendingRefreshes.get(key);
63917
63948
  if (existingPromise) {
63918
63949
  this.stats.coalescedRequests++;
63950
+ this.emitEvent("coalesced", key);
63919
63951
  this.options.logger.debug("Request coalesced", { key });
63920
63952
  return existingPromise;
63921
63953
  }
@@ -63949,6 +63981,7 @@ class StampedeProtectedCache {
63949
63981
  const timeoutPromise = new Promise((_, reject) => {
63950
63982
  timeoutHandle = setTimeout(() => {
63951
63983
  this.stats.loadTimeouts++;
63984
+ this.emitEvent("load_timeout", key);
63952
63985
  // Mark the invocation abandoned BEFORE evicting the pin: a retry that
63953
63986
  // starts now must never be overwritten by this loader's late result.
63954
63987
  invocation.abandoned = true;
@@ -64005,6 +64038,7 @@ class StampedeProtectedCache {
64005
64038
  }
64006
64039
  catch (error) {
64007
64040
  this.stats.refreshErrors++;
64041
+ this.emitEvent("refresh_error", key);
64008
64042
  const loadTime = Date.now() - startTime;
64009
64043
  this.options.logger.error("Failed to load data", {
64010
64044
  key,
@@ -64037,6 +64071,7 @@ class StampedeProtectedCache {
64037
64071
  this.loadWithCoalescing(key, loader, ttl)
64038
64072
  .then(() => {
64039
64073
  this.stats.backgroundRefreshes++;
64074
+ this.emitEvent("background_refresh", key);
64040
64075
  this.options.logger.debug("Background refresh completed", { key });
64041
64076
  })
64042
64077
  .catch((error) => {