@adaptic/utils 0.0.1003 → 0.0.1004

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
@@ -14563,17 +14563,17 @@ var hasRequiredBrowser;
14563
14563
  function requireBrowser () {
14564
14564
  if (hasRequiredBrowser) return browser.exports;
14565
14565
  hasRequiredBrowser = 1;
14566
- (function (module, exports) {
14566
+ (function (module, exports$1) {
14567
14567
  /**
14568
14568
  * This is the web browser implementation of `debug()`.
14569
14569
  */
14570
14570
 
14571
- exports.formatArgs = formatArgs;
14572
- exports.save = save;
14573
- exports.load = load;
14574
- exports.useColors = useColors;
14575
- exports.storage = localstorage();
14576
- exports.destroy = (() => {
14571
+ exports$1.formatArgs = formatArgs;
14572
+ exports$1.save = save;
14573
+ exports$1.load = load;
14574
+ exports$1.useColors = useColors;
14575
+ exports$1.storage = localstorage();
14576
+ exports$1.destroy = (() => {
14577
14577
  let warned = false;
14578
14578
 
14579
14579
  return () => {
@@ -14588,7 +14588,7 @@ function requireBrowser () {
14588
14588
  * Colors.
14589
14589
  */
14590
14590
 
14591
- exports.colors = [
14591
+ exports$1.colors = [
14592
14592
  '#0000CC',
14593
14593
  '#0000FF',
14594
14594
  '#0033CC',
@@ -14753,7 +14753,7 @@ function requireBrowser () {
14753
14753
  *
14754
14754
  * @api public
14755
14755
  */
14756
- exports.log = console.debug || console.log || (() => {});
14756
+ exports$1.log = console.debug || console.log || (() => {});
14757
14757
 
14758
14758
  /**
14759
14759
  * Save `namespaces`.
@@ -14764,9 +14764,9 @@ function requireBrowser () {
14764
14764
  function save(namespaces) {
14765
14765
  try {
14766
14766
  if (namespaces) {
14767
- exports.storage.setItem('debug', namespaces);
14767
+ exports$1.storage.setItem('debug', namespaces);
14768
14768
  } else {
14769
- exports.storage.removeItem('debug');
14769
+ exports$1.storage.removeItem('debug');
14770
14770
  }
14771
14771
  } catch (error) {
14772
14772
  // Swallow
@@ -14783,7 +14783,7 @@ function requireBrowser () {
14783
14783
  function load() {
14784
14784
  let r;
14785
14785
  try {
14786
- r = exports.storage.getItem('debug') || exports.storage.getItem('DEBUG') ;
14786
+ r = exports$1.storage.getItem('debug') || exports$1.storage.getItem('DEBUG') ;
14787
14787
  } catch (error) {
14788
14788
  // Swallow
14789
14789
  // XXX (@Qix-) should we be logging these?
@@ -14819,7 +14819,7 @@ function requireBrowser () {
14819
14819
  }
14820
14820
  }
14821
14821
 
14822
- module.exports = requireCommon()(exports);
14822
+ module.exports = requireCommon()(exports$1);
14823
14823
 
14824
14824
  const {formatters} = module.exports;
14825
14825
 
@@ -15008,7 +15008,7 @@ var hasRequiredNode$1;
15008
15008
  function requireNode$1 () {
15009
15009
  if (hasRequiredNode$1) return node$1.exports;
15010
15010
  hasRequiredNode$1 = 1;
15011
- (function (module, exports) {
15011
+ (function (module, exports$1) {
15012
15012
  const tty = require$$1$1;
15013
15013
  const util = require$$1$2;
15014
15014
 
@@ -15016,13 +15016,13 @@ function requireNode$1 () {
15016
15016
  * This is the Node.js implementation of `debug()`.
15017
15017
  */
15018
15018
 
15019
- exports.init = init;
15020
- exports.log = log;
15021
- exports.formatArgs = formatArgs;
15022
- exports.save = save;
15023
- exports.load = load;
15024
- exports.useColors = useColors;
15025
- exports.destroy = util.deprecate(
15019
+ exports$1.init = init;
15020
+ exports$1.log = log;
15021
+ exports$1.formatArgs = formatArgs;
15022
+ exports$1.save = save;
15023
+ exports$1.load = load;
15024
+ exports$1.useColors = useColors;
15025
+ exports$1.destroy = util.deprecate(
15026
15026
  () => {},
15027
15027
  'Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.'
15028
15028
  );
@@ -15031,7 +15031,7 @@ function requireNode$1 () {
15031
15031
  * Colors.
15032
15032
  */
15033
15033
 
15034
- exports.colors = [6, 2, 3, 4, 5, 1];
15034
+ exports$1.colors = [6, 2, 3, 4, 5, 1];
15035
15035
 
15036
15036
  try {
15037
15037
  // Optional dependency (as in, doesn't need to be installed, NOT like optionalDependencies in package.json)
@@ -15039,7 +15039,7 @@ function requireNode$1 () {
15039
15039
  const supportsColor = requireSupportsColor();
15040
15040
 
15041
15041
  if (supportsColor && (supportsColor.stderr || supportsColor).level >= 2) {
15042
- exports.colors = [
15042
+ exports$1.colors = [
15043
15043
  20,
15044
15044
  21,
15045
15045
  26,
@@ -15128,7 +15128,7 @@ function requireNode$1 () {
15128
15128
  * $ DEBUG_COLORS=no DEBUG_DEPTH=10 DEBUG_SHOW_HIDDEN=enabled node script.js
15129
15129
  */
15130
15130
 
15131
- exports.inspectOpts = Object.keys(process.env).filter(key => {
15131
+ exports$1.inspectOpts = Object.keys(process.env).filter(key => {
15132
15132
  return /^debug_/i.test(key);
15133
15133
  }).reduce((obj, key) => {
15134
15134
  // Camel-case
@@ -15160,8 +15160,8 @@ function requireNode$1 () {
15160
15160
  */
15161
15161
 
15162
15162
  function useColors() {
15163
- return 'colors' in exports.inspectOpts ?
15164
- Boolean(exports.inspectOpts.colors) :
15163
+ return 'colors' in exports$1.inspectOpts ?
15164
+ Boolean(exports$1.inspectOpts.colors) :
15165
15165
  tty.isatty(process.stderr.fd);
15166
15166
  }
15167
15167
 
@@ -15187,7 +15187,7 @@ function requireNode$1 () {
15187
15187
  }
15188
15188
 
15189
15189
  function getDate() {
15190
- if (exports.inspectOpts.hideDate) {
15190
+ if (exports$1.inspectOpts.hideDate) {
15191
15191
  return '';
15192
15192
  }
15193
15193
  return new Date().toISOString() + ' ';
@@ -15198,7 +15198,7 @@ function requireNode$1 () {
15198
15198
  */
15199
15199
 
15200
15200
  function log(...args) {
15201
- return process.stderr.write(util.formatWithOptions(exports.inspectOpts, ...args) + '\n');
15201
+ return process.stderr.write(util.formatWithOptions(exports$1.inspectOpts, ...args) + '\n');
15202
15202
  }
15203
15203
 
15204
15204
  /**
@@ -15238,13 +15238,13 @@ function requireNode$1 () {
15238
15238
  function init(debug) {
15239
15239
  debug.inspectOpts = {};
15240
15240
 
15241
- const keys = Object.keys(exports.inspectOpts);
15241
+ const keys = Object.keys(exports$1.inspectOpts);
15242
15242
  for (let i = 0; i < keys.length; i++) {
15243
- debug.inspectOpts[keys[i]] = exports.inspectOpts[keys[i]];
15243
+ debug.inspectOpts[keys[i]] = exports$1.inspectOpts[keys[i]];
15244
15244
  }
15245
15245
  }
15246
15246
 
15247
- module.exports = requireCommon()(exports);
15247
+ module.exports = requireCommon()(exports$1);
15248
15248
 
15249
15249
  const {formatters} = module.exports;
15250
15250
 
@@ -15818,7 +15818,7 @@ function requireFollowRedirects () {
15818
15818
  // Wraps the key/value object of protocols with redirect functionality
15819
15819
  function wrap(protocols) {
15820
15820
  // Default settings
15821
- var exports = {
15821
+ var exports$1 = {
15822
15822
  maxRedirects: 21,
15823
15823
  maxBodyLength: 10 * 1024 * 1024,
15824
15824
  };
@@ -15828,7 +15828,7 @@ function requireFollowRedirects () {
15828
15828
  Object.keys(protocols).forEach(function (scheme) {
15829
15829
  var protocol = scheme + ":";
15830
15830
  var nativeProtocol = nativeProtocols[protocol] = protocols[scheme];
15831
- var wrappedProtocol = exports[scheme] = Object.create(nativeProtocol);
15831
+ var wrappedProtocol = exports$1[scheme] = Object.create(nativeProtocol);
15832
15832
 
15833
15833
  // Executes a request, following redirects
15834
15834
  function request(input, options, callback) {
@@ -15851,8 +15851,8 @@ function requireFollowRedirects () {
15851
15851
 
15852
15852
  // Set defaults
15853
15853
  options = Object.assign({
15854
- maxRedirects: exports.maxRedirects,
15855
- maxBodyLength: exports.maxBodyLength,
15854
+ maxRedirects: exports$1.maxRedirects,
15855
+ maxBodyLength: exports$1.maxBodyLength,
15856
15856
  }, input, options);
15857
15857
  options.nativeProtocols = nativeProtocols;
15858
15858
  if (!isString(options.host) && !isString(options.hostname)) {
@@ -15877,7 +15877,7 @@ function requireFollowRedirects () {
15877
15877
  get: { value: get, configurable: true, enumerable: true, writable: true },
15878
15878
  });
15879
15879
  });
15880
- return exports;
15880
+ return exports$1;
15881
15881
  }
15882
15882
 
15883
15883
  function noop() { /* empty */ }
@@ -17483,7 +17483,7 @@ var hasRequiredLodash;
17483
17483
  function requireLodash () {
17484
17484
  if (hasRequiredLodash) return lodash$1.exports;
17485
17485
  hasRequiredLodash = 1;
17486
- (function (module, exports) {
17486
+ (function (module, exports$1) {
17487
17487
  (function() {
17488
17488
 
17489
17489
  /** Used as a safe reference for `undefined` in pre-ES5 environments. */
@@ -17914,7 +17914,7 @@ function requireLodash () {
17914
17914
  var root = freeGlobal || freeSelf || Function('return this')();
17915
17915
 
17916
17916
  /** Detect free variable `exports`. */
17917
- var freeExports = exports && !exports.nodeType && exports;
17917
+ var freeExports = exports$1 && !exports$1.nodeType && exports$1;
17918
17918
 
17919
17919
  /** Detect free variable `module`. */
17920
17920
  var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module;
@@ -35744,12 +35744,12 @@ var hasRequiredIsBuffer;
35744
35744
  function requireIsBuffer () {
35745
35745
  if (hasRequiredIsBuffer) return isBuffer.exports;
35746
35746
  hasRequiredIsBuffer = 1;
35747
- (function (module, exports) {
35747
+ (function (module, exports$1) {
35748
35748
  var root = require_root(),
35749
35749
  stubFalse = requireStubFalse();
35750
35750
 
35751
35751
  /** Detect free variable `exports`. */
35752
- var freeExports = exports && !exports.nodeType && exports;
35752
+ var freeExports = exports$1 && !exports$1.nodeType && exports$1;
35753
35753
 
35754
35754
  /** Detect free variable `module`. */
35755
35755
  var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module;
@@ -35969,11 +35969,11 @@ var hasRequired_nodeUtil;
35969
35969
  function require_nodeUtil () {
35970
35970
  if (hasRequired_nodeUtil) return _nodeUtil.exports;
35971
35971
  hasRequired_nodeUtil = 1;
35972
- (function (module, exports) {
35972
+ (function (module, exports$1) {
35973
35973
  var freeGlobal = require_freeGlobal();
35974
35974
 
35975
35975
  /** Detect free variable `exports`. */
35976
- var freeExports = exports && !exports.nodeType && exports;
35976
+ var freeExports = exports$1 && !exports$1.nodeType && exports$1;
35977
35977
 
35978
35978
  /** Detect free variable `module`. */
35979
35979
  var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module;
@@ -44895,7 +44895,7 @@ var hasRequiredSafeBuffer;
44895
44895
  function requireSafeBuffer () {
44896
44896
  if (hasRequiredSafeBuffer) return safeBuffer.exports;
44897
44897
  hasRequiredSafeBuffer = 1;
44898
- (function (module, exports) {
44898
+ (function (module, exports$1) {
44899
44899
  /* eslint-disable node/no-deprecated-api */
44900
44900
  var buffer = require$$0$5;
44901
44901
  var Buffer = buffer.Buffer;
@@ -44910,8 +44910,8 @@ function requireSafeBuffer () {
44910
44910
  module.exports = buffer;
44911
44911
  } else {
44912
44912
  // Copy properties from require('buffer')
44913
- copyProps(buffer, exports);
44914
- exports.Buffer = SafeBuffer;
44913
+ copyProps(buffer, exports$1);
44914
+ exports$1.Buffer = SafeBuffer;
44915
44915
  }
44916
44916
 
44917
44917
  function SafeBuffer (arg, encodingOrOffset, length) {
@@ -48109,22 +48109,22 @@ var hasRequiredReadable;
48109
48109
  function requireReadable () {
48110
48110
  if (hasRequiredReadable) return readable.exports;
48111
48111
  hasRequiredReadable = 1;
48112
- (function (module, exports) {
48112
+ (function (module, exports$1) {
48113
48113
  var Stream = require$$0$4;
48114
48114
  if (process.env.READABLE_STREAM === 'disable' && Stream) {
48115
48115
  module.exports = Stream.Readable;
48116
48116
  Object.assign(module.exports, Stream);
48117
48117
  module.exports.Stream = Stream;
48118
48118
  } else {
48119
- exports = module.exports = require_stream_readable();
48120
- exports.Stream = Stream || exports;
48121
- exports.Readable = exports;
48122
- exports.Writable = require_stream_writable();
48123
- exports.Duplex = require_stream_duplex();
48124
- exports.Transform = require_stream_transform();
48125
- exports.PassThrough = require_stream_passthrough();
48126
- exports.finished = requireEndOfStream();
48127
- exports.pipeline = requirePipeline();
48119
+ exports$1 = module.exports = require_stream_readable();
48120
+ exports$1.Stream = Stream || exports$1;
48121
+ exports$1.Readable = exports$1;
48122
+ exports$1.Writable = require_stream_writable();
48123
+ exports$1.Duplex = require_stream_duplex();
48124
+ exports$1.Transform = require_stream_transform();
48125
+ exports$1.PassThrough = require_stream_passthrough();
48126
+ exports$1.finished = requireEndOfStream();
48127
+ exports$1.pipeline = requirePipeline();
48128
48128
  }
48129
48129
  } (readable, readable.exports));
48130
48130
  return readable.exports;
@@ -49559,12 +49559,12 @@ var hasRequiredWebsocket;
49559
49559
  function requireWebsocket () {
49560
49560
  if (hasRequiredWebsocket) return websocket$1;
49561
49561
  hasRequiredWebsocket = 1;
49562
- (function (exports) {
49562
+ (function (exports$1) {
49563
49563
  var __importDefault = (websocket$1 && websocket$1.__importDefault) || function (mod) {
49564
49564
  return (mod && mod.__esModule) ? mod : { "default": mod };
49565
49565
  };
49566
- Object.defineProperty(exports, "__esModule", { value: true });
49567
- exports.AlpacaWebsocket = exports.ERROR = exports.CONN_ERROR = exports.EVENT = exports.STATE = void 0;
49566
+ Object.defineProperty(exports$1, "__esModule", { value: true });
49567
+ exports$1.AlpacaWebsocket = exports$1.ERROR = exports$1.CONN_ERROR = exports$1.EVENT = exports$1.STATE = void 0;
49568
49568
  const events_1 = __importDefault(require$$0$1);
49569
49569
  const ws_1 = __importDefault(requireWs());
49570
49570
  const msgpack5_1 = __importDefault(requireMsgpack5());
@@ -49578,7 +49578,7 @@ function requireWebsocket () {
49578
49578
  STATE["DISCONNECTED"] = "disconnected";
49579
49579
  STATE["WAITING_TO_CONNECT"] = "waiting to connect";
49580
49580
  STATE["WAITING_TO_RECONNECT"] = "waiting to reconnect";
49581
- })(STATE || (exports.STATE = STATE = {}));
49581
+ })(STATE || (exports$1.STATE = STATE = {}));
49582
49582
  // Client events
49583
49583
  var EVENT;
49584
49584
  (function (EVENT) {
@@ -49597,9 +49597,9 @@ function requireWebsocket () {
49597
49597
  EVENT["CORRECTIONS"] = "corrections";
49598
49598
  EVENT["ORDERBOOKS"] = "orderbooks";
49599
49599
  EVENT["NEWS"] = "news";
49600
- })(EVENT || (exports.EVENT = EVENT = {}));
49600
+ })(EVENT || (exports$1.EVENT = EVENT = {}));
49601
49601
  // Connection errors by code
49602
- exports.CONN_ERROR = new Map([
49602
+ exports$1.CONN_ERROR = new Map([
49603
49603
  [400, "invalid syntax"],
49604
49604
  [401, "not authenticated"],
49605
49605
  [402, "auth failed"],
@@ -49618,7 +49618,7 @@ function requireWebsocket () {
49618
49618
  ERROR["MISSING_SECERT_KEY"] = "missing secret key";
49619
49619
  ERROR["MISSING_API_KEY"] = "missing api key";
49620
49620
  ERROR["UNEXPECTED_MESSAGE"] = "unexpected message";
49621
- })(ERROR || (exports.ERROR = ERROR = {}));
49621
+ })(ERROR || (exports$1.ERROR = ERROR = {}));
49622
49622
  class AlpacaWebsocket extends events_1.default.EventEmitter {
49623
49623
  constructor(options) {
49624
49624
  super();
@@ -49775,7 +49775,7 @@ function requireWebsocket () {
49775
49775
  this.updateSubscriptions(data[0]);
49776
49776
  break;
49777
49777
  case "error":
49778
- this.emit(EVENT.CLIENT_ERROR, exports.CONN_ERROR.get(data[0].code));
49778
+ this.emit(EVENT.CLIENT_ERROR, exports$1.CONN_ERROR.get(data[0].code));
49779
49779
  break;
49780
49780
  default:
49781
49781
  this.dataHandler(data);
@@ -49804,7 +49804,7 @@ function requireWebsocket () {
49804
49804
  }
49805
49805
  }
49806
49806
  }
49807
- exports.AlpacaWebsocket = AlpacaWebsocket;
49807
+ exports$1.AlpacaWebsocket = AlpacaWebsocket;
49808
49808
  } (websocket$1));
49809
49809
  return websocket$1;
49810
49810
  }
@@ -50438,8 +50438,8 @@ var hasRequiredWebsockets;
50438
50438
  function requireWebsockets () {
50439
50439
  if (hasRequiredWebsockets) return websockets;
50440
50440
  hasRequiredWebsockets = 1;
50441
- (function (exports) {
50442
- Object.defineProperty(exports, "__esModule", { value: true });
50441
+ (function (exports$1) {
50442
+ Object.defineProperty(exports$1, "__esModule", { value: true });
50443
50443
  const events = require$$0$1;
50444
50444
  const WebSocket = requireWs();
50445
50445
  const entity = requireEntity();
@@ -50454,7 +50454,7 @@ function requireWebsockets () {
50454
50454
  STATE.DISCONNECTED = "disconnected";
50455
50455
  STATE.WAITING_TO_CONNECT = "waiting to connect";
50456
50456
  STATE.WAITING_TO_RECONNECT = "waiting to reconnect";
50457
- })((STATE = exports.STATE || (exports.STATE = {})));
50457
+ })((STATE = exports$1.STATE || (exports$1.STATE = {})));
50458
50458
  // Client events
50459
50459
  var EVENT;
50460
50460
  (function (EVENT) {
@@ -50468,7 +50468,7 @@ function requireWebsockets () {
50468
50468
  EVENT.STOCK_QUOTES = "stock_quotes";
50469
50469
  EVENT.STOCK_AGG_SEC = "stock_agg_sec";
50470
50470
  EVENT.STOCK_AGG_MIN = "stock_agg_min";
50471
- })((EVENT = exports.EVENT || (exports.EVENT = {})));
50471
+ })((EVENT = exports$1.EVENT || (exports$1.EVENT = {})));
50472
50472
  // Connection errors Each of these will also emit EVENT.ERROR
50473
50473
  var ERROR;
50474
50474
  (function (ERROR) {
@@ -50477,7 +50477,7 @@ function requireWebsockets () {
50477
50477
  ERROR.MISSING_API_KEY = "missing api key";
50478
50478
  ERROR.MISSING_SECRET_KEY = "missing secret key";
50479
50479
  ERROR.UNKNOWN = "unknown error";
50480
- })((ERROR = exports.ERROR || (exports.ERROR = {})));
50480
+ })((ERROR = exports$1.ERROR || (exports$1.ERROR = {})));
50481
50481
  /**
50482
50482
  * AlpacaStreamClient manages a connection to Alpaca's websocket api
50483
50483
  */
@@ -50790,7 +50790,7 @@ function requireWebsockets () {
50790
50790
  }
50791
50791
  }
50792
50792
  }
50793
- exports.AlpacaStreamClient = AlpacaStreamClient;
50793
+ exports$1.AlpacaStreamClient = AlpacaStreamClient;
50794
50794
  } (websockets));
50795
50795
  return websockets;
50796
50796
  }
@@ -51042,13 +51042,13 @@ var hasRequiredDist;
51042
51042
  function requireDist () {
51043
51043
  if (hasRequiredDist) return dist$1.exports;
51044
51044
  hasRequiredDist = 1;
51045
- (function (module, exports) {
51045
+ (function (module, exports$1) {
51046
51046
  var __importDefault = (dist && dist.__importDefault) || function (mod) {
51047
51047
  return (mod && mod.__esModule) ? mod : { "default": mod };
51048
51048
  };
51049
- Object.defineProperty(exports, "__esModule", { value: true });
51049
+ Object.defineProperty(exports$1, "__esModule", { value: true });
51050
51050
  const alpaca_trade_api_1 = __importDefault(requireAlpacaTradeApi());
51051
- exports.default = alpaca_trade_api_1.default;
51051
+ exports$1.default = alpaca_trade_api_1.default;
51052
51052
  module.exports = alpaca_trade_api_1.default;
51053
51053
  } (dist$1, dist$1.exports));
51054
51054
  return dist$1.exports;
@@ -63157,6 +63157,7 @@ class StampedeProtectedCache {
63157
63157
  coalescedRequests: 0,
63158
63158
  backgroundRefreshes: 0,
63159
63159
  refreshErrors: 0,
63160
+ loadTimeouts: 0,
63160
63161
  };
63161
63162
  constructor(options) {
63162
63163
  this.options = {
@@ -63430,6 +63431,7 @@ class StampedeProtectedCache {
63430
63431
  coalescedRequests: this.stats.coalescedRequests,
63431
63432
  backgroundRefreshes: this.stats.backgroundRefreshes,
63432
63433
  refreshErrors: this.stats.refreshErrors,
63434
+ loadTimeouts: this.stats.loadTimeouts,
63433
63435
  };
63434
63436
  }
63435
63437
  /**
@@ -63480,8 +63482,9 @@ class StampedeProtectedCache {
63480
63482
  this.options.logger.debug("Request coalesced", { key });
63481
63483
  return existingPromise;
63482
63484
  }
63483
- // Create new promise and store it
63484
- const promise = this.loadAndCache(key, loader, ttl);
63485
+ // Create new promise and store it — bounded by loadTimeoutMs so a
63486
+ // never-settling loader cannot pin the key (see loadWithTimeout).
63487
+ const promise = this.loadWithTimeout(key, loader, ttl);
63485
63488
  this.pendingRefreshes.set(key, promise);
63486
63489
  try {
63487
63490
  const result = await promise;
@@ -63492,6 +63495,51 @@ class StampedeProtectedCache {
63492
63495
  this.pendingRefreshes.delete(key);
63493
63496
  }
63494
63497
  }
63498
+ /**
63499
+ * Race {@link loadAndCache} against the configured load timeout.
63500
+ *
63501
+ * On timeout: rejects with a typed timeout error, evicts the pending
63502
+ * single-flight entry so the NEXT caller retries with a fresh loader
63503
+ * (instead of coalescing onto the hung one), and attaches a settlement
63504
+ * observer to the abandoned loader so its eventual resolution/rejection
63505
+ * is logged rather than surfacing as an unhandled rejection.
63506
+ */
63507
+ async loadWithTimeout(key, loader, ttl) {
63508
+ const timeoutMs = this.options.loadTimeoutMs ?? 30000;
63509
+ const loadPromise = this.loadAndCache(key, loader, ttl);
63510
+ let timeoutHandle;
63511
+ const timeoutPromise = new Promise((_, reject) => {
63512
+ timeoutHandle = setTimeout(() => {
63513
+ this.stats.loadTimeouts++;
63514
+ // Evict the pin so the next caller retries fresh.
63515
+ this.pendingRefreshes.delete(key);
63516
+ this.options.logger.warn("Cache loader timed out — pin evicted", {
63517
+ key,
63518
+ timeoutMs,
63519
+ });
63520
+ // Observe the abandoned loader; never let it become unhandled.
63521
+ loadPromise
63522
+ .then(() => {
63523
+ this.options.logger.warn("Abandoned cache loader eventually resolved", { key });
63524
+ })
63525
+ .catch((error) => {
63526
+ this.options.logger.warn("Abandoned cache loader eventually rejected", {
63527
+ key,
63528
+ error: error instanceof Error ? error.message : String(error),
63529
+ });
63530
+ });
63531
+ reject(new Error(`StampedeProtectedCache loader timed out after ${timeoutMs}ms for key "${key}"`));
63532
+ }, timeoutMs);
63533
+ });
63534
+ try {
63535
+ return await Promise.race([loadPromise, timeoutPromise]);
63536
+ }
63537
+ finally {
63538
+ if (timeoutHandle !== undefined) {
63539
+ clearTimeout(timeoutHandle);
63540
+ }
63541
+ }
63542
+ }
63495
63543
  /**
63496
63544
  * Load data and cache it
63497
63545
  */
@@ -63641,6 +63689,7 @@ const DEFAULT_CACHE_OPTIONS = {
63641
63689
  minJitter: 0.9, // 90%
63642
63690
  maxJitter: 1.1, // 110%
63643
63691
  enableBackgroundRefresh: true,
63692
+ loadTimeoutMs: 30000, // 30s hard loader ceiling (anti-pinning)
63644
63693
  };
63645
63694
 
63646
63695
  /**