@musistudio/claude-code-router 1.0.3 → 1.0.5

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/cli.js CHANGED
@@ -335,10 +335,10 @@ var require_browser = __commonJS({
335
335
  exports2.useColors = useColors;
336
336
  exports2.storage = localstorage();
337
337
  exports2.destroy = /* @__PURE__ */ (() => {
338
- let warned = false;
338
+ let warned2 = false;
339
339
  return () => {
340
- if (!warned) {
341
- warned = true;
340
+ if (!warned2) {
341
+ warned2 = true;
342
342
  console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.");
343
343
  }
344
344
  };
@@ -2938,10 +2938,10 @@ var require_lib2 = __commonJS({
2938
2938
  var zlib = _interopDefault(require("zlib"));
2939
2939
  var Readable2 = Stream2.Readable;
2940
2940
  var BUFFER = Symbol("buffer");
2941
- var TYPE = Symbol("type");
2941
+ var TYPE2 = Symbol("type");
2942
2942
  var Blob3 = class _Blob {
2943
2943
  constructor() {
2944
- this[TYPE] = "";
2944
+ this[TYPE2] = "";
2945
2945
  const blobParts = arguments[0];
2946
2946
  const options = arguments[1];
2947
2947
  const buffers = [];
@@ -2970,14 +2970,14 @@ var require_lib2 = __commonJS({
2970
2970
  this[BUFFER] = Buffer.concat(buffers);
2971
2971
  let type = options && options.type !== void 0 && String(options.type).toLowerCase();
2972
2972
  if (type && !/[^\u0020-\u007E]/.test(type)) {
2973
- this[TYPE] = type;
2973
+ this[TYPE2] = type;
2974
2974
  }
2975
2975
  }
2976
2976
  get size() {
2977
2977
  return this[BUFFER].length;
2978
2978
  }
2979
2979
  get type() {
2980
- return this[TYPE];
2980
+ return this[TYPE2];
2981
2981
  }
2982
2982
  text() {
2983
2983
  return Promise.resolve(this[BUFFER].toString());
@@ -9181,12 +9181,12 @@ var require_utf16 = __commonJS({
9181
9181
  return this.decoder.end();
9182
9182
  };
9183
9183
  function detectEncoding(buf, defaultEncoding) {
9184
- var enc = defaultEncoding || "utf-16le";
9184
+ var enc2 = defaultEncoding || "utf-16le";
9185
9185
  if (buf.length >= 2) {
9186
9186
  if (buf[0] == 254 && buf[1] == 255)
9187
- enc = "utf-16be";
9187
+ enc2 = "utf-16be";
9188
9188
  else if (buf[0] == 255 && buf[1] == 254)
9189
- enc = "utf-16le";
9189
+ enc2 = "utf-16le";
9190
9190
  else {
9191
9191
  var asciiCharsLE = 0, asciiCharsBE = 0, _len = Math.min(buf.length - buf.length % 2, 64);
9192
9192
  for (var i2 = 0; i2 < _len; i2 += 2) {
@@ -9194,12 +9194,12 @@ var require_utf16 = __commonJS({
9194
9194
  if (buf[i2] !== 0 && buf[i2 + 1] === 0) asciiCharsLE++;
9195
9195
  }
9196
9196
  if (asciiCharsBE > asciiCharsLE)
9197
- enc = "utf-16be";
9197
+ enc2 = "utf-16be";
9198
9198
  else if (asciiCharsBE < asciiCharsLE)
9199
- enc = "utf-16le";
9199
+ enc2 = "utf-16le";
9200
9200
  }
9201
9201
  }
9202
- return enc;
9202
+ return enc2;
9203
9203
  }
9204
9204
  }
9205
9205
  });
@@ -11884,12 +11884,12 @@ var require_encodings = __commonJS({
11884
11884
  ];
11885
11885
  for (i2 = 0; i2 < modules.length; i2++) {
11886
11886
  module2 = modules[i2];
11887
- for (enc in module2)
11888
- if (Object.prototype.hasOwnProperty.call(module2, enc))
11889
- exports2[enc] = module2[enc];
11887
+ for (enc2 in module2)
11888
+ if (Object.prototype.hasOwnProperty.call(module2, enc2))
11889
+ exports2[enc2] = module2[enc2];
11890
11890
  }
11891
11891
  var module2;
11892
- var enc;
11892
+ var enc2;
11893
11893
  var i2;
11894
11894
  }
11895
11895
  });
@@ -12023,8 +12023,8 @@ var require_extend_node = __commonJS({
12023
12023
  "utf16le": true,
12024
12024
  "utf-16le": true
12025
12025
  };
12026
- Buffer2.isNativeEncoding = function(enc) {
12027
- return enc && nodeNativeEncodings[enc.toLowerCase()];
12026
+ Buffer2.isNativeEncoding = function(enc2) {
12027
+ return enc2 && nodeNativeEncodings[enc2.toLowerCase()];
12028
12028
  };
12029
12029
  var SlowBuffer = require("buffer").SlowBuffer;
12030
12030
  original.SlowBufferToString = SlowBuffer.prototype.toString;
@@ -12126,9 +12126,9 @@ var require_extend_node = __commonJS({
12126
12126
  if (iconv.supportsStreams) {
12127
12127
  var Readable2 = require("stream").Readable;
12128
12128
  original.ReadableSetEncoding = Readable2.prototype.setEncoding;
12129
- Readable2.prototype.setEncoding = function setEncoding(enc, options) {
12130
- this._readableState.decoder = iconv.getDecoder(enc, options);
12131
- this._readableState.encoding = enc;
12129
+ Readable2.prototype.setEncoding = function setEncoding(enc2, options) {
12130
+ this._readableState.decoder = iconv.getDecoder(enc2, options);
12131
+ this._readableState.encoding = enc2;
12132
12132
  };
12133
12133
  Readable2.prototype.collect = iconv._collect;
12134
12134
  }
@@ -12187,9 +12187,9 @@ var require_lib3 = __commonJS({
12187
12187
  var trail = decoder.end();
12188
12188
  return trail ? res + trail : res;
12189
12189
  };
12190
- iconv.encodingExists = function encodingExists(enc) {
12190
+ iconv.encodingExists = function encodingExists(enc2) {
12191
12191
  try {
12192
- iconv.getCodec(enc);
12192
+ iconv.getCodec(enc2);
12193
12193
  return true;
12194
12194
  } catch (e2) {
12195
12195
  return false;
@@ -12201,32 +12201,32 @@ var require_lib3 = __commonJS({
12201
12201
  iconv.getCodec = function getCodec(encoding) {
12202
12202
  if (!iconv.encodings)
12203
12203
  iconv.encodings = require_encodings();
12204
- var enc = iconv._canonicalizeEncoding(encoding);
12204
+ var enc2 = iconv._canonicalizeEncoding(encoding);
12205
12205
  var codecOptions = {};
12206
12206
  while (true) {
12207
- var codec = iconv._codecDataCache[enc];
12207
+ var codec = iconv._codecDataCache[enc2];
12208
12208
  if (codec)
12209
12209
  return codec;
12210
- var codecDef = iconv.encodings[enc];
12210
+ var codecDef = iconv.encodings[enc2];
12211
12211
  switch (typeof codecDef) {
12212
12212
  case "string":
12213
- enc = codecDef;
12213
+ enc2 = codecDef;
12214
12214
  break;
12215
12215
  case "object":
12216
12216
  for (var key in codecDef)
12217
12217
  codecOptions[key] = codecDef[key];
12218
12218
  if (!codecOptions.encodingName)
12219
- codecOptions.encodingName = enc;
12220
- enc = codecDef.type;
12219
+ codecOptions.encodingName = enc2;
12220
+ enc2 = codecDef.type;
12221
12221
  break;
12222
12222
  case "function":
12223
12223
  if (!codecOptions.encodingName)
12224
- codecOptions.encodingName = enc;
12224
+ codecOptions.encodingName = enc2;
12225
12225
  codec = new codecDef(codecOptions, iconv);
12226
12226
  iconv._codecDataCache[codecOptions.encodingName] = codec;
12227
12227
  return codec;
12228
12228
  default:
12229
- throw new Error("Encoding not recognized: '" + encoding + "' (searched as: '" + enc + "')");
12229
+ throw new Error("Encoding not recognized: '" + encoding + "' (searched as: '" + enc2 + "')");
12230
12230
  }
12231
12231
  }
12232
12232
  };
@@ -25261,17 +25261,17 @@ var require_router = __commonJS({
25261
25261
  var toString = Object.prototype.toString;
25262
25262
  var proto = module2.exports = function(options) {
25263
25263
  var opts = options || {};
25264
- function router(req, res, next) {
25265
- router.handle(req, res, next);
25266
- }
25267
- setPrototypeOf(router, proto);
25268
- router.params = {};
25269
- router._params = [];
25270
- router.caseSensitive = opts.caseSensitive;
25271
- router.mergeParams = opts.mergeParams;
25272
- router.strict = opts.strict;
25273
- router.stack = [];
25274
- return router;
25264
+ function router2(req, res, next) {
25265
+ router2.handle(req, res, next);
25266
+ }
25267
+ setPrototypeOf(router2, proto);
25268
+ router2.params = {};
25269
+ router2._params = [];
25270
+ router2.caseSensitive = opts.caseSensitive;
25271
+ router2.mergeParams = opts.mergeParams;
25272
+ router2.strict = opts.strict;
25273
+ router2.stack = [];
25274
+ return router2;
25275
25275
  };
25276
25276
  proto.param = function param(name, fn) {
25277
25277
  if (typeof name === "function") {
@@ -27951,17 +27951,17 @@ var require_application = __commonJS({
27951
27951
  }
27952
27952
  };
27953
27953
  app.handle = function handle(req, res, callback) {
27954
- var router = this._router;
27954
+ var router2 = this._router;
27955
27955
  var done = callback || finalhandler(req, res, {
27956
27956
  env: this.get("env"),
27957
27957
  onerror: logerror.bind(this)
27958
27958
  });
27959
- if (!router) {
27959
+ if (!router2) {
27960
27960
  debug2("no routes defined on app");
27961
27961
  done();
27962
27962
  return;
27963
27963
  }
27964
- router.handle(req, res, done);
27964
+ router2.handle(req, res, done);
27965
27965
  };
27966
27966
  app.use = function use(fn) {
27967
27967
  var offset = 0;
@@ -27981,15 +27981,15 @@ var require_application = __commonJS({
27981
27981
  throw new TypeError("app.use() requires a middleware function");
27982
27982
  }
27983
27983
  this.lazyrouter();
27984
- var router = this._router;
27984
+ var router2 = this._router;
27985
27985
  fns.forEach(function(fn2) {
27986
27986
  if (!fn2 || !fn2.handle || !fn2.set) {
27987
- return router.use(path4, fn2);
27987
+ return router2.use(path4, fn2);
27988
27988
  }
27989
27989
  debug2(".use app under %s", path4);
27990
27990
  fn2.mountpath = path4;
27991
27991
  fn2.parent = this;
27992
- router.use(path4, function mounted_app(req, res, next) {
27992
+ router2.use(path4, function mounted_app(req, res, next) {
27993
27993
  var orig = req.app;
27994
27994
  fn2.handle(req, res, function(err) {
27995
27995
  setPrototypeOf(req, orig.request);
@@ -28975,14 +28975,14 @@ var require_cookie = __commonJS({
28975
28975
  return min;
28976
28976
  }
28977
28977
  function serialize(name, val, opt) {
28978
- var enc = opt && opt.encode || encodeURIComponent;
28979
- if (typeof enc !== "function") {
28978
+ var enc2 = opt && opt.encode || encodeURIComponent;
28979
+ if (typeof enc2 !== "function") {
28980
28980
  throw new TypeError("option encode is invalid");
28981
28981
  }
28982
28982
  if (!cookieNameRegExp.test(name)) {
28983
28983
  throw new TypeError("argument name is invalid");
28984
28984
  }
28985
- var value = enc(val);
28985
+ var value = enc2(val);
28986
28986
  if (!cookieValueRegExp.test(value)) {
28987
28987
  throw new TypeError("argument val is invalid");
28988
28988
  }
@@ -29873,6 +29873,436 @@ var require_express2 = __commonJS({
29873
29873
  }
29874
29874
  });
29875
29875
 
29876
+ // node_modules/tiktoken/tiktoken_bg.cjs
29877
+ var require_tiktoken_bg = __commonJS({
29878
+ "node_modules/tiktoken/tiktoken_bg.cjs"(exports2, module2) {
29879
+ var wasm;
29880
+ module2.exports.__wbg_set_wasm = function(val) {
29881
+ wasm = val;
29882
+ };
29883
+ var lTextDecoder = typeof TextDecoder === "undefined" ? (0, module2.require)("util").TextDecoder : TextDecoder;
29884
+ var cachedTextDecoder = new lTextDecoder("utf-8", { ignoreBOM: true, fatal: true });
29885
+ cachedTextDecoder.decode();
29886
+ var cachedUint8ArrayMemory0 = null;
29887
+ function getUint8ArrayMemory0() {
29888
+ if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {
29889
+ cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);
29890
+ }
29891
+ return cachedUint8ArrayMemory0;
29892
+ }
29893
+ function getStringFromWasm0(ptr, len) {
29894
+ ptr = ptr >>> 0;
29895
+ return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
29896
+ }
29897
+ var heap = new Array(128).fill(void 0);
29898
+ heap.push(void 0, null, true, false);
29899
+ var heap_next = heap.length;
29900
+ function addHeapObject(obj) {
29901
+ if (heap_next === heap.length) heap.push(heap.length + 1);
29902
+ const idx = heap_next;
29903
+ heap_next = heap[idx];
29904
+ heap[idx] = obj;
29905
+ return idx;
29906
+ }
29907
+ function handleError(f2, args) {
29908
+ try {
29909
+ return f2.apply(this, args);
29910
+ } catch (e2) {
29911
+ wasm.__wbindgen_export_0(addHeapObject(e2));
29912
+ }
29913
+ }
29914
+ function getObject(idx) {
29915
+ return heap[idx];
29916
+ }
29917
+ function dropObject(idx) {
29918
+ if (idx < 132) return;
29919
+ heap[idx] = heap_next;
29920
+ heap_next = idx;
29921
+ }
29922
+ function takeObject(idx) {
29923
+ const ret = getObject(idx);
29924
+ dropObject(idx);
29925
+ return ret;
29926
+ }
29927
+ var WASM_VECTOR_LEN = 0;
29928
+ var lTextEncoder = typeof TextEncoder === "undefined" ? (0, module2.require)("util").TextEncoder : TextEncoder;
29929
+ var cachedTextEncoder = new lTextEncoder("utf-8");
29930
+ var encodeString = typeof cachedTextEncoder.encodeInto === "function" ? function(arg, view) {
29931
+ return cachedTextEncoder.encodeInto(arg, view);
29932
+ } : function(arg, view) {
29933
+ const buf = cachedTextEncoder.encode(arg);
29934
+ view.set(buf);
29935
+ return {
29936
+ read: arg.length,
29937
+ written: buf.length
29938
+ };
29939
+ };
29940
+ function passStringToWasm0(arg, malloc, realloc) {
29941
+ if (realloc === void 0) {
29942
+ const buf = cachedTextEncoder.encode(arg);
29943
+ const ptr2 = malloc(buf.length, 1) >>> 0;
29944
+ getUint8ArrayMemory0().subarray(ptr2, ptr2 + buf.length).set(buf);
29945
+ WASM_VECTOR_LEN = buf.length;
29946
+ return ptr2;
29947
+ }
29948
+ let len = arg.length;
29949
+ let ptr = malloc(len, 1) >>> 0;
29950
+ const mem = getUint8ArrayMemory0();
29951
+ let offset = 0;
29952
+ for (; offset < len; offset++) {
29953
+ const code = arg.charCodeAt(offset);
29954
+ if (code > 127) break;
29955
+ mem[ptr + offset] = code;
29956
+ }
29957
+ if (offset !== len) {
29958
+ if (offset !== 0) {
29959
+ arg = arg.slice(offset);
29960
+ }
29961
+ ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;
29962
+ const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len);
29963
+ const ret = encodeString(arg, view);
29964
+ offset += ret.written;
29965
+ ptr = realloc(ptr, len, offset, 1) >>> 0;
29966
+ }
29967
+ WASM_VECTOR_LEN = offset;
29968
+ return ptr;
29969
+ }
29970
+ function isLikeNone(x2) {
29971
+ return x2 === void 0 || x2 === null;
29972
+ }
29973
+ var cachedDataViewMemory0 = null;
29974
+ function getDataViewMemory0() {
29975
+ if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || cachedDataViewMemory0.buffer.detached === void 0 && cachedDataViewMemory0.buffer !== wasm.memory.buffer) {
29976
+ cachedDataViewMemory0 = new DataView(wasm.memory.buffer);
29977
+ }
29978
+ return cachedDataViewMemory0;
29979
+ }
29980
+ var cachedUint32ArrayMemory0 = null;
29981
+ function getUint32ArrayMemory0() {
29982
+ if (cachedUint32ArrayMemory0 === null || cachedUint32ArrayMemory0.byteLength === 0) {
29983
+ cachedUint32ArrayMemory0 = new Uint32Array(wasm.memory.buffer);
29984
+ }
29985
+ return cachedUint32ArrayMemory0;
29986
+ }
29987
+ function getArrayU32FromWasm0(ptr, len) {
29988
+ ptr = ptr >>> 0;
29989
+ return getUint32ArrayMemory0().subarray(ptr / 4, ptr / 4 + len);
29990
+ }
29991
+ function passArray8ToWasm0(arg, malloc) {
29992
+ const ptr = malloc(arg.length * 1, 1) >>> 0;
29993
+ getUint8ArrayMemory0().set(arg, ptr / 1);
29994
+ WASM_VECTOR_LEN = arg.length;
29995
+ return ptr;
29996
+ }
29997
+ function passArray32ToWasm0(arg, malloc) {
29998
+ const ptr = malloc(arg.length * 4, 4) >>> 0;
29999
+ getUint32ArrayMemory0().set(arg, ptr / 4);
30000
+ WASM_VECTOR_LEN = arg.length;
30001
+ return ptr;
30002
+ }
30003
+ function getArrayU8FromWasm0(ptr, len) {
30004
+ ptr = ptr >>> 0;
30005
+ return getUint8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len);
30006
+ }
30007
+ module2.exports.get_encoding = function(encoding, extend_special_tokens) {
30008
+ if (wasm == null) throw new Error("tiktoken: WASM binary has not been propery initialized.");
30009
+ try {
30010
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
30011
+ const ptr0 = passStringToWasm0(encoding, wasm.__wbindgen_export_1, wasm.__wbindgen_export_2);
30012
+ const len0 = WASM_VECTOR_LEN;
30013
+ wasm.get_encoding(retptr, ptr0, len0, addHeapObject(extend_special_tokens));
30014
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
30015
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
30016
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
30017
+ if (r2) {
30018
+ throw takeObject(r1);
30019
+ }
30020
+ return Tiktoken.__wrap(r0);
30021
+ } finally {
30022
+ wasm.__wbindgen_add_to_stack_pointer(16);
30023
+ }
30024
+ };
30025
+ module2.exports.encoding_for_model = function(model, extend_special_tokens) {
30026
+ if (wasm == null) throw new Error("tiktoken: WASM binary has not been propery initialized.");
30027
+ try {
30028
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
30029
+ const ptr0 = passStringToWasm0(model, wasm.__wbindgen_export_1, wasm.__wbindgen_export_2);
30030
+ const len0 = WASM_VECTOR_LEN;
30031
+ wasm.encoding_for_model(retptr, ptr0, len0, addHeapObject(extend_special_tokens));
30032
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
30033
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
30034
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
30035
+ if (r2) {
30036
+ throw takeObject(r1);
30037
+ }
30038
+ return Tiktoken.__wrap(r0);
30039
+ } finally {
30040
+ wasm.__wbindgen_add_to_stack_pointer(16);
30041
+ }
30042
+ };
30043
+ var TiktokenFinalization = typeof FinalizationRegistry === "undefined" ? { register: () => {
30044
+ }, unregister: () => {
30045
+ } } : new FinalizationRegistry((ptr) => wasm.__wbg_tiktoken_free(ptr >>> 0, 1));
30046
+ var Tiktoken = class _Tiktoken {
30047
+ /**
30048
+ * @param {string} tiktoken_bfe
30049
+ * @param {any} special_tokens
30050
+ * @param {string} pat_str
30051
+ */
30052
+ constructor(tiktoken_bfe, special_tokens, pat_str) {
30053
+ if (wasm == null) throw new Error("tiktoken: WASM binary has not been propery initialized.");
30054
+ const ptr0 = passStringToWasm0(tiktoken_bfe, wasm.__wbindgen_export_1, wasm.__wbindgen_export_2);
30055
+ const len0 = WASM_VECTOR_LEN;
30056
+ const ptr1 = passStringToWasm0(pat_str, wasm.__wbindgen_export_1, wasm.__wbindgen_export_2);
30057
+ const len1 = WASM_VECTOR_LEN;
30058
+ const ret = wasm.tiktoken_new(ptr0, len0, addHeapObject(special_tokens), ptr1, len1);
30059
+ this.__wbg_ptr = ret >>> 0;
30060
+ TiktokenFinalization.register(this, this.__wbg_ptr, this);
30061
+ return this;
30062
+ }
30063
+ /** @returns {string | undefined} */
30064
+ get name() {
30065
+ try {
30066
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
30067
+ wasm.tiktoken_name(retptr, this.__wbg_ptr);
30068
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
30069
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
30070
+ let v1;
30071
+ if (r0 !== 0) {
30072
+ v1 = getStringFromWasm0(r0, r1).slice();
30073
+ wasm.__wbindgen_export_3(r0, r1 * 1, 1);
30074
+ }
30075
+ return v1;
30076
+ } finally {
30077
+ wasm.__wbindgen_add_to_stack_pointer(16);
30078
+ }
30079
+ }
30080
+ static __wrap(ptr) {
30081
+ ptr = ptr >>> 0;
30082
+ const obj = Object.create(_Tiktoken.prototype);
30083
+ obj.__wbg_ptr = ptr;
30084
+ TiktokenFinalization.register(obj, obj.__wbg_ptr, obj);
30085
+ return obj;
30086
+ }
30087
+ __destroy_into_raw() {
30088
+ const ptr = this.__wbg_ptr;
30089
+ this.__wbg_ptr = 0;
30090
+ TiktokenFinalization.unregister(this);
30091
+ return ptr;
30092
+ }
30093
+ free() {
30094
+ if (wasm == null) throw new Error("tiktoken: WASM binary has not been propery initialized.");
30095
+ const ptr = this.__destroy_into_raw();
30096
+ wasm.__wbg_tiktoken_free(ptr, 0);
30097
+ }
30098
+ /**
30099
+ * @param {string} text
30100
+ * @param {any} allowed_special
30101
+ * @param {any} disallowed_special
30102
+ * @returns {Uint32Array}
30103
+ */
30104
+ encode(text, allowed_special, disallowed_special) {
30105
+ if (wasm == null) throw new Error("tiktoken: WASM binary has not been propery initialized.");
30106
+ try {
30107
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
30108
+ const ptr0 = passStringToWasm0(text, wasm.__wbindgen_export_1, wasm.__wbindgen_export_2);
30109
+ const len0 = WASM_VECTOR_LEN;
30110
+ wasm.tiktoken_encode(retptr, this.__wbg_ptr, ptr0, len0, addHeapObject(allowed_special), addHeapObject(disallowed_special));
30111
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
30112
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
30113
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
30114
+ var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
30115
+ if (r3) {
30116
+ throw takeObject(r2);
30117
+ }
30118
+ var v2 = getArrayU32FromWasm0(r0, r1).slice();
30119
+ wasm.__wbindgen_export_3(r0, r1 * 4, 4);
30120
+ return v2;
30121
+ } finally {
30122
+ wasm.__wbindgen_add_to_stack_pointer(16);
30123
+ }
30124
+ }
30125
+ /**
30126
+ * @param {string} text
30127
+ * @returns {Uint32Array}
30128
+ */
30129
+ encode_ordinary(text) {
30130
+ if (wasm == null) throw new Error("tiktoken: WASM binary has not been propery initialized.");
30131
+ try {
30132
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
30133
+ const ptr0 = passStringToWasm0(text, wasm.__wbindgen_export_1, wasm.__wbindgen_export_2);
30134
+ const len0 = WASM_VECTOR_LEN;
30135
+ wasm.tiktoken_encode_ordinary(retptr, this.__wbg_ptr, ptr0, len0);
30136
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
30137
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
30138
+ var v2 = getArrayU32FromWasm0(r0, r1).slice();
30139
+ wasm.__wbindgen_export_3(r0, r1 * 4, 4);
30140
+ return v2;
30141
+ } finally {
30142
+ wasm.__wbindgen_add_to_stack_pointer(16);
30143
+ }
30144
+ }
30145
+ /**
30146
+ * @param {string} text
30147
+ * @param {any} allowed_special
30148
+ * @param {any} disallowed_special
30149
+ * @returns {any}
30150
+ */
30151
+ encode_with_unstable(text, allowed_special, disallowed_special) {
30152
+ if (wasm == null) throw new Error("tiktoken: WASM binary has not been propery initialized.");
30153
+ try {
30154
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
30155
+ const ptr0 = passStringToWasm0(text, wasm.__wbindgen_export_1, wasm.__wbindgen_export_2);
30156
+ const len0 = WASM_VECTOR_LEN;
30157
+ wasm.tiktoken_encode_with_unstable(retptr, this.__wbg_ptr, ptr0, len0, addHeapObject(allowed_special), addHeapObject(disallowed_special));
30158
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
30159
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
30160
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
30161
+ if (r2) {
30162
+ throw takeObject(r1);
30163
+ }
30164
+ return takeObject(r0);
30165
+ } finally {
30166
+ wasm.__wbindgen_add_to_stack_pointer(16);
30167
+ }
30168
+ }
30169
+ /**
30170
+ * @param {Uint8Array} bytes
30171
+ * @returns {number}
30172
+ */
30173
+ encode_single_token(bytes) {
30174
+ if (wasm == null) throw new Error("tiktoken: WASM binary has not been propery initialized.");
30175
+ const ptr0 = passArray8ToWasm0(bytes, wasm.__wbindgen_export_1);
30176
+ const len0 = WASM_VECTOR_LEN;
30177
+ const ret = wasm.tiktoken_encode_single_token(this.__wbg_ptr, ptr0, len0);
30178
+ return ret >>> 0;
30179
+ }
30180
+ /**
30181
+ * @param {Uint32Array} tokens
30182
+ * @returns {Uint8Array}
30183
+ */
30184
+ decode(tokens) {
30185
+ if (wasm == null) throw new Error("tiktoken: WASM binary has not been propery initialized.");
30186
+ try {
30187
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
30188
+ const ptr0 = passArray32ToWasm0(tokens, wasm.__wbindgen_export_1);
30189
+ const len0 = WASM_VECTOR_LEN;
30190
+ wasm.tiktoken_decode(retptr, this.__wbg_ptr, ptr0, len0);
30191
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
30192
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
30193
+ var v2 = getArrayU8FromWasm0(r0, r1).slice();
30194
+ wasm.__wbindgen_export_3(r0, r1 * 1, 1);
30195
+ return v2;
30196
+ } finally {
30197
+ wasm.__wbindgen_add_to_stack_pointer(16);
30198
+ }
30199
+ }
30200
+ /**
30201
+ * @param {number} token
30202
+ * @returns {Uint8Array}
30203
+ */
30204
+ decode_single_token_bytes(token) {
30205
+ if (wasm == null) throw new Error("tiktoken: WASM binary has not been propery initialized.");
30206
+ try {
30207
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
30208
+ wasm.tiktoken_decode_single_token_bytes(retptr, this.__wbg_ptr, token);
30209
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
30210
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
30211
+ var v1 = getArrayU8FromWasm0(r0, r1).slice();
30212
+ wasm.__wbindgen_export_3(r0, r1 * 1, 1);
30213
+ return v1;
30214
+ } finally {
30215
+ wasm.__wbindgen_add_to_stack_pointer(16);
30216
+ }
30217
+ }
30218
+ /** @returns {any} */
30219
+ token_byte_values() {
30220
+ if (wasm == null) throw new Error("tiktoken: WASM binary has not been propery initialized.");
30221
+ const ret = wasm.tiktoken_token_byte_values(this.__wbg_ptr);
30222
+ return takeObject(ret);
30223
+ }
30224
+ };
30225
+ module2.exports.Tiktoken = Tiktoken;
30226
+ module2.exports.__wbg_parse_def2e24ef1252aff = function() {
30227
+ return handleError(function(arg0, arg1) {
30228
+ const ret = JSON.parse(getStringFromWasm0(arg0, arg1));
30229
+ return addHeapObject(ret);
30230
+ }, arguments);
30231
+ };
30232
+ module2.exports.__wbg_stringify_f7ed6987935b4a24 = function() {
30233
+ return handleError(function(arg0) {
30234
+ const ret = JSON.stringify(getObject(arg0));
30235
+ return addHeapObject(ret);
30236
+ }, arguments);
30237
+ };
30238
+ module2.exports.__wbindgen_error_new = function(arg0, arg1) {
30239
+ const ret = new Error(getStringFromWasm0(arg0, arg1));
30240
+ return addHeapObject(ret);
30241
+ };
30242
+ module2.exports.__wbindgen_is_undefined = function(arg0) {
30243
+ const ret = getObject(arg0) === void 0;
30244
+ return ret;
30245
+ };
30246
+ module2.exports.__wbindgen_object_drop_ref = function(arg0) {
30247
+ takeObject(arg0);
30248
+ };
30249
+ module2.exports.__wbindgen_string_get = function(arg0, arg1) {
30250
+ if (wasm == null) throw new Error("tiktoken: WASM binary has not been propery initialized.");
30251
+ const obj = getObject(arg1);
30252
+ const ret = typeof obj === "string" ? obj : void 0;
30253
+ var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_export_1, wasm.__wbindgen_export_2);
30254
+ var len1 = WASM_VECTOR_LEN;
30255
+ getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
30256
+ getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
30257
+ };
30258
+ module2.exports.__wbindgen_throw = function(arg0, arg1) {
30259
+ throw new Error(getStringFromWasm0(arg0, arg1));
30260
+ };
30261
+ }
30262
+ });
30263
+
30264
+ // node_modules/tiktoken/tiktoken.cjs
30265
+ var require_tiktoken = __commonJS({
30266
+ "node_modules/tiktoken/tiktoken.cjs"(exports2) {
30267
+ var wasm = require_tiktoken_bg();
30268
+ var imports = {};
30269
+ imports["./tiktoken_bg.js"] = wasm;
30270
+ var path4 = require("path");
30271
+ var fs4 = require("fs");
30272
+ var candidates = __dirname.split(path4.sep).reduce((memo, _2, index, array) => {
30273
+ const prefix = array.slice(0, index + 1).join(path4.sep) + path4.sep;
30274
+ if (!prefix.includes("node_modules" + path4.sep)) {
30275
+ memo.unshift(
30276
+ path4.join(
30277
+ prefix,
30278
+ "node_modules",
30279
+ "tiktoken",
30280
+ "",
30281
+ "./tiktoken_bg.wasm"
30282
+ )
30283
+ );
30284
+ }
30285
+ return memo;
30286
+ }, []);
30287
+ candidates.unshift(path4.join(__dirname, "./tiktoken_bg.wasm"));
30288
+ var bytes = null;
30289
+ for (const candidate of candidates) {
30290
+ try {
30291
+ bytes = fs4.readFileSync(candidate);
30292
+ break;
30293
+ } catch {
30294
+ }
30295
+ }
30296
+ if (bytes == null) throw new Error("Missing tiktoken_bg.wasm");
30297
+ var wasmModule = new WebAssembly.Module(bytes);
30298
+ var wasmInstance = new WebAssembly.Instance(wasmModule, imports);
30299
+ wasm.__wbg_set_wasm(wasmInstance.exports);
30300
+ exports2["get_encoding"] = wasm["get_encoding"];
30301
+ exports2["encoding_for_model"] = wasm["encoding_for_model"];
30302
+ exports2["Tiktoken"] = wasm["Tiktoken"];
30303
+ }
30304
+ });
30305
+
29876
30306
  // src/index.ts
29877
30307
  var import_fs3 = require("fs");
29878
30308
  var import_promises3 = require("fs/promises");
@@ -36487,6 +36917,7 @@ var HOME_DIR = import_node_path.default.join(import_node_os.default.homedir(), "
36487
36917
  var CONFIG_FILE = `${HOME_DIR}/config.json`;
36488
36918
  var PLUGINS_DIR = `${HOME_DIR}/plugins`;
36489
36919
  var PID_FILE = import_node_path.default.join(HOME_DIR, ".claude-code-router.pid");
36920
+ var REFERENCE_COUNT_FILE = "/tmp/claude-code-reference-count.txt";
36490
36921
  var DEFAULT_CONFIG = {
36491
36922
  log: false,
36492
36923
  OPENAI_API_KEY: "",
@@ -36499,6 +36930,8 @@ function getOpenAICommonOptions() {
36499
36930
  const options = {};
36500
36931
  if (process.env.PROXY_URL) {
36501
36932
  options.httpAgent = new import_https_proxy_agent.HttpsProxyAgent(process.env.PROXY_URL);
36933
+ } else if (process.env.HTTPS_PROXY) {
36934
+ options.httpAgent = new import_https_proxy_agent.HttpsProxyAgent(process.env.HTTPS_PROXY);
36502
36935
  }
36503
36936
  return options;
36504
36937
  }
@@ -36552,6 +36985,7 @@ var writeConfigFile = async (config) => {
36552
36985
  var initConfig = async () => {
36553
36986
  const config = await readConfigFile();
36554
36987
  Object.assign(process.env, config);
36988
+ return config;
36555
36989
  };
36556
36990
  var createClient = (options) => {
36557
36991
  const client = new openai_default({
@@ -36563,7 +36997,7 @@ var createClient = (options) => {
36563
36997
 
36564
36998
  // src/server.ts
36565
36999
  var import_express = __toESM(require_express2());
36566
- var createServer = (port) => {
37000
+ var createServer = async (port) => {
36567
37001
  const app = (0, import_express.default)();
36568
37002
  app.use(import_express.default.json({ limit: "500mb" }));
36569
37003
  return {
@@ -36971,6 +37405,7 @@ var formatRequest = async (req, res, next) => {
36971
37405
  res.setHeader("Cache-Control", "no-cache");
36972
37406
  res.setHeader("Connection", "keep-alive");
36973
37407
  req.body = data;
37408
+ console.log(JSON.stringify(data.messages, null, 2));
36974
37409
  } catch (error) {
36975
37410
  console.error("Error in request processing:", error);
36976
37411
  const errorCompletion = {
@@ -36978,7 +37413,7 @@ var formatRequest = async (req, res, next) => {
36978
37413
  yield {
36979
37414
  id: `error_${Date.now()}`,
36980
37415
  created: Math.floor(Date.now() / 1e3),
36981
- model: "gpt-3.5-turbo",
37416
+ model,
36982
37417
  object: "chat.completion.chunk",
36983
37418
  choices: [
36984
37419
  {
@@ -37014,23 +37449,123 @@ import_node_module.default._load = function(request, parent, isMain) {
37014
37449
  return originalLoad.call(this, request, parent, isMain);
37015
37450
  };
37016
37451
  var rewriteBody = async (req, res, next) => {
37017
- if (!process.env.usePlugin) {
37452
+ if (!req.config.usePlugins) {
37018
37453
  return next();
37019
37454
  }
37020
- const pluginPath = import_node_path3.default.join(PLUGINS_DIR, `${process.env.usePlugin}.js`);
37455
+ for (const plugin of req.config.usePlugins) {
37456
+ const pluginPath = import_node_path3.default.join(PLUGINS_DIR, `${plugin.trim()}.js`);
37457
+ try {
37458
+ await (0, import_promises2.access)(pluginPath);
37459
+ const rewritePlugin = require(pluginPath);
37460
+ await rewritePlugin(req, res);
37461
+ } catch (e2) {
37462
+ console.error(e2);
37463
+ }
37464
+ }
37465
+ next();
37466
+ };
37467
+
37468
+ // src/middlewares/router.ts
37469
+ var import_tiktoken = __toESM(require_tiktoken());
37470
+ var enc = (0, import_tiktoken.get_encoding)("cl100k_base");
37471
+ var getUseModel = (req, tokenCount) => {
37472
+ if (tokenCount > 1e3 * 32) {
37473
+ log("Using long context model due to token count:", tokenCount);
37474
+ const [provider2, model2] = req.config.Router.longContext.split(",");
37475
+ return {
37476
+ provider: provider2,
37477
+ model: model2
37478
+ };
37479
+ }
37480
+ if (req.body.model?.startsWith("claude-3-5-haiku")) {
37481
+ log("Using background model for ", req.body.model);
37482
+ const [provider2, model2] = req.config.Router.background.split(",");
37483
+ return {
37484
+ provider: provider2,
37485
+ model: model2
37486
+ };
37487
+ }
37488
+ if (req.body.thinking) {
37489
+ log("Using think model for ", req.body.thinking);
37490
+ const [provider2, model2] = req.config.Router.think.split(",");
37491
+ return {
37492
+ provider: provider2,
37493
+ model: model2
37494
+ };
37495
+ }
37496
+ const [provider, model] = req.body.model.split(",");
37497
+ if (provider && model) {
37498
+ return {
37499
+ provider,
37500
+ model
37501
+ };
37502
+ }
37503
+ return {
37504
+ provider: "default",
37505
+ model: req.config.OPENAI_MODEL
37506
+ };
37507
+ };
37508
+ var router = async (req, res, next) => {
37509
+ const { messages, system = [], tools } = req.body;
37021
37510
  try {
37022
- await (0, import_promises2.access)(pluginPath);
37023
- const rewritePlugin = require(pluginPath);
37024
- rewritePlugin(req, res, next);
37025
- } catch (e2) {
37026
- console.error(e2);
37511
+ let tokenCount = 0;
37512
+ if (Array.isArray(messages)) {
37513
+ messages.forEach((message) => {
37514
+ if (typeof message.content === "string") {
37515
+ tokenCount += enc.encode(message.content).length;
37516
+ } else if (Array.isArray(message.content)) {
37517
+ message.content.forEach((contentPart) => {
37518
+ if (contentPart.type === "text") {
37519
+ tokenCount += enc.encode(contentPart.text).length;
37520
+ } else if (contentPart.type === "tool_use") {
37521
+ tokenCount += enc.encode(
37522
+ JSON.stringify(contentPart.input)
37523
+ ).length;
37524
+ } else if (contentPart.type === "tool_result") {
37525
+ tokenCount += enc.encode(contentPart.content || "").length;
37526
+ }
37527
+ });
37528
+ }
37529
+ });
37530
+ }
37531
+ if (typeof system === "string") {
37532
+ tokenCount += enc.encode(system).length;
37533
+ } else if (Array.isArray(system)) {
37534
+ system.forEach((item) => {
37535
+ if (item.type !== "text") return;
37536
+ if (typeof item.text === "string") {
37537
+ tokenCount += enc.encode(item.text).length;
37538
+ } else if (Array.isArray(item.text)) {
37539
+ item.text.forEach((textPart) => {
37540
+ tokenCount += enc.encode(textPart || "").length;
37541
+ });
37542
+ }
37543
+ });
37544
+ }
37545
+ if (tools) {
37546
+ tools.forEach((tool) => {
37547
+ if (tool.description) {
37548
+ tokenCount += enc.encode(tool.name + tool.description).length;
37549
+ }
37550
+ if (tool.input_schema) {
37551
+ tokenCount += enc.encode(JSON.stringify(tool.input_schema)).length;
37552
+ }
37553
+ });
37554
+ }
37555
+ const { provider, model } = getUseModel(req, tokenCount);
37556
+ req.provider = provider;
37557
+ req.body.model = model;
37558
+ } catch (error) {
37559
+ log("Error in router middleware:", error.message);
37560
+ req.provider = "default";
37561
+ req.body.model = req.config.OPENAI_MODEL;
37562
+ } finally {
37027
37563
  next();
37028
37564
  }
37029
37565
  };
37030
37566
 
37031
37567
  // src/utils/processCheck.ts
37032
37568
  var import_fs2 = require("fs");
37033
- var REFERENCE_COUNT_FILE = "/tmp/claude-code-reference-count.txt";
37034
37569
  function incrementReferenceCount() {
37035
37570
  let count = 0;
37036
37571
  if ((0, import_fs2.existsSync)(REFERENCE_COUNT_FILE)) {
@@ -37102,6 +37637,1393 @@ function getServiceInfo() {
37102
37637
  };
37103
37638
  }
37104
37639
 
37640
+ // node_modules/lru-cache/dist/esm/index.js
37641
+ var perf = typeof performance === "object" && performance && typeof performance.now === "function" ? performance : Date;
37642
+ var warned = /* @__PURE__ */ new Set();
37643
+ var PROCESS = typeof process === "object" && !!process ? process : {};
37644
+ var emitWarning = (msg, type, code, fn) => {
37645
+ typeof PROCESS.emitWarning === "function" ? PROCESS.emitWarning(msg, type, code, fn) : console.error(`[${code}] ${type}: ${msg}`);
37646
+ };
37647
+ var AC = globalThis.AbortController;
37648
+ var AS = globalThis.AbortSignal;
37649
+ if (typeof AC === "undefined") {
37650
+ AS = class AbortSignal {
37651
+ onabort;
37652
+ _onabort = [];
37653
+ reason;
37654
+ aborted = false;
37655
+ addEventListener(_2, fn) {
37656
+ this._onabort.push(fn);
37657
+ }
37658
+ };
37659
+ AC = class AbortController {
37660
+ constructor() {
37661
+ warnACPolyfill();
37662
+ }
37663
+ signal = new AS();
37664
+ abort(reason) {
37665
+ if (this.signal.aborted)
37666
+ return;
37667
+ this.signal.reason = reason;
37668
+ this.signal.aborted = true;
37669
+ for (const fn of this.signal._onabort) {
37670
+ fn(reason);
37671
+ }
37672
+ this.signal.onabort?.(reason);
37673
+ }
37674
+ };
37675
+ let printACPolyfillWarning = PROCESS.env?.LRU_CACHE_IGNORE_AC_WARNING !== "1";
37676
+ const warnACPolyfill = () => {
37677
+ if (!printACPolyfillWarning)
37678
+ return;
37679
+ printACPolyfillWarning = false;
37680
+ emitWarning("AbortController is not defined. If using lru-cache in node 14, load an AbortController polyfill from the `node-abort-controller` package. A minimal polyfill is provided for use by LRUCache.fetch(), but it should not be relied upon in other contexts (eg, passing it to other APIs that use AbortController/AbortSignal might have undesirable effects). You may disable this with LRU_CACHE_IGNORE_AC_WARNING=1 in the env.", "NO_ABORT_CONTROLLER", "ENOTSUP", warnACPolyfill);
37681
+ };
37682
+ }
37683
+ var shouldWarn = (code) => !warned.has(code);
37684
+ var TYPE = Symbol("type");
37685
+ var isPosInt = (n2) => n2 && n2 === Math.floor(n2) && n2 > 0 && isFinite(n2);
37686
+ var getUintArray = (max) => !isPosInt(max) ? null : max <= Math.pow(2, 8) ? Uint8Array : max <= Math.pow(2, 16) ? Uint16Array : max <= Math.pow(2, 32) ? Uint32Array : max <= Number.MAX_SAFE_INTEGER ? ZeroArray : null;
37687
+ var ZeroArray = class extends Array {
37688
+ constructor(size) {
37689
+ super(size);
37690
+ this.fill(0);
37691
+ }
37692
+ };
37693
+ var Stack = class _Stack {
37694
+ heap;
37695
+ length;
37696
+ // private constructor
37697
+ static #constructing = false;
37698
+ static create(max) {
37699
+ const HeapCls = getUintArray(max);
37700
+ if (!HeapCls)
37701
+ return [];
37702
+ _Stack.#constructing = true;
37703
+ const s2 = new _Stack(max, HeapCls);
37704
+ _Stack.#constructing = false;
37705
+ return s2;
37706
+ }
37707
+ constructor(max, HeapCls) {
37708
+ if (!_Stack.#constructing) {
37709
+ throw new TypeError("instantiate Stack using Stack.create(n)");
37710
+ }
37711
+ this.heap = new HeapCls(max);
37712
+ this.length = 0;
37713
+ }
37714
+ push(n2) {
37715
+ this.heap[this.length++] = n2;
37716
+ }
37717
+ pop() {
37718
+ return this.heap[--this.length];
37719
+ }
37720
+ };
37721
+ var LRUCache = class _LRUCache {
37722
+ // options that cannot be changed without disaster
37723
+ #max;
37724
+ #maxSize;
37725
+ #dispose;
37726
+ #onInsert;
37727
+ #disposeAfter;
37728
+ #fetchMethod;
37729
+ #memoMethod;
37730
+ /**
37731
+ * {@link LRUCache.OptionsBase.ttl}
37732
+ */
37733
+ ttl;
37734
+ /**
37735
+ * {@link LRUCache.OptionsBase.ttlResolution}
37736
+ */
37737
+ ttlResolution;
37738
+ /**
37739
+ * {@link LRUCache.OptionsBase.ttlAutopurge}
37740
+ */
37741
+ ttlAutopurge;
37742
+ /**
37743
+ * {@link LRUCache.OptionsBase.updateAgeOnGet}
37744
+ */
37745
+ updateAgeOnGet;
37746
+ /**
37747
+ * {@link LRUCache.OptionsBase.updateAgeOnHas}
37748
+ */
37749
+ updateAgeOnHas;
37750
+ /**
37751
+ * {@link LRUCache.OptionsBase.allowStale}
37752
+ */
37753
+ allowStale;
37754
+ /**
37755
+ * {@link LRUCache.OptionsBase.noDisposeOnSet}
37756
+ */
37757
+ noDisposeOnSet;
37758
+ /**
37759
+ * {@link LRUCache.OptionsBase.noUpdateTTL}
37760
+ */
37761
+ noUpdateTTL;
37762
+ /**
37763
+ * {@link LRUCache.OptionsBase.maxEntrySize}
37764
+ */
37765
+ maxEntrySize;
37766
+ /**
37767
+ * {@link LRUCache.OptionsBase.sizeCalculation}
37768
+ */
37769
+ sizeCalculation;
37770
+ /**
37771
+ * {@link LRUCache.OptionsBase.noDeleteOnFetchRejection}
37772
+ */
37773
+ noDeleteOnFetchRejection;
37774
+ /**
37775
+ * {@link LRUCache.OptionsBase.noDeleteOnStaleGet}
37776
+ */
37777
+ noDeleteOnStaleGet;
37778
+ /**
37779
+ * {@link LRUCache.OptionsBase.allowStaleOnFetchAbort}
37780
+ */
37781
+ allowStaleOnFetchAbort;
37782
+ /**
37783
+ * {@link LRUCache.OptionsBase.allowStaleOnFetchRejection}
37784
+ */
37785
+ allowStaleOnFetchRejection;
37786
+ /**
37787
+ * {@link LRUCache.OptionsBase.ignoreFetchAbort}
37788
+ */
37789
+ ignoreFetchAbort;
37790
+ // computed properties
37791
+ #size;
37792
+ #calculatedSize;
37793
+ #keyMap;
37794
+ #keyList;
37795
+ #valList;
37796
+ #next;
37797
+ #prev;
37798
+ #head;
37799
+ #tail;
37800
+ #free;
37801
+ #disposed;
37802
+ #sizes;
37803
+ #starts;
37804
+ #ttls;
37805
+ #hasDispose;
37806
+ #hasFetchMethod;
37807
+ #hasDisposeAfter;
37808
+ #hasOnInsert;
37809
+ /**
37810
+ * Do not call this method unless you need to inspect the
37811
+ * inner workings of the cache. If anything returned by this
37812
+ * object is modified in any way, strange breakage may occur.
37813
+ *
37814
+ * These fields are private for a reason!
37815
+ *
37816
+ * @internal
37817
+ */
37818
+ static unsafeExposeInternals(c2) {
37819
+ return {
37820
+ // properties
37821
+ starts: c2.#starts,
37822
+ ttls: c2.#ttls,
37823
+ sizes: c2.#sizes,
37824
+ keyMap: c2.#keyMap,
37825
+ keyList: c2.#keyList,
37826
+ valList: c2.#valList,
37827
+ next: c2.#next,
37828
+ prev: c2.#prev,
37829
+ get head() {
37830
+ return c2.#head;
37831
+ },
37832
+ get tail() {
37833
+ return c2.#tail;
37834
+ },
37835
+ free: c2.#free,
37836
+ // methods
37837
+ isBackgroundFetch: (p2) => c2.#isBackgroundFetch(p2),
37838
+ backgroundFetch: (k2, index, options, context) => c2.#backgroundFetch(k2, index, options, context),
37839
+ moveToTail: (index) => c2.#moveToTail(index),
37840
+ indexes: (options) => c2.#indexes(options),
37841
+ rindexes: (options) => c2.#rindexes(options),
37842
+ isStale: (index) => c2.#isStale(index)
37843
+ };
37844
+ }
37845
+ // Protected read-only members
37846
+ /**
37847
+ * {@link LRUCache.OptionsBase.max} (read-only)
37848
+ */
37849
+ get max() {
37850
+ return this.#max;
37851
+ }
37852
+ /**
37853
+ * {@link LRUCache.OptionsBase.maxSize} (read-only)
37854
+ */
37855
+ get maxSize() {
37856
+ return this.#maxSize;
37857
+ }
37858
+ /**
37859
+ * The total computed size of items in the cache (read-only)
37860
+ */
37861
+ get calculatedSize() {
37862
+ return this.#calculatedSize;
37863
+ }
37864
+ /**
37865
+ * The number of items stored in the cache (read-only)
37866
+ */
37867
+ get size() {
37868
+ return this.#size;
37869
+ }
37870
+ /**
37871
+ * {@link LRUCache.OptionsBase.fetchMethod} (read-only)
37872
+ */
37873
+ get fetchMethod() {
37874
+ return this.#fetchMethod;
37875
+ }
37876
+ get memoMethod() {
37877
+ return this.#memoMethod;
37878
+ }
37879
+ /**
37880
+ * {@link LRUCache.OptionsBase.dispose} (read-only)
37881
+ */
37882
+ get dispose() {
37883
+ return this.#dispose;
37884
+ }
37885
+ /**
37886
+ * {@link LRUCache.OptionsBase.onInsert} (read-only)
37887
+ */
37888
+ get onInsert() {
37889
+ return this.#onInsert;
37890
+ }
37891
+ /**
37892
+ * {@link LRUCache.OptionsBase.disposeAfter} (read-only)
37893
+ */
37894
+ get disposeAfter() {
37895
+ return this.#disposeAfter;
37896
+ }
37897
+ constructor(options) {
37898
+ const { max = 0, ttl, ttlResolution = 1, ttlAutopurge, updateAgeOnGet, updateAgeOnHas, allowStale, dispose, onInsert, disposeAfter, noDisposeOnSet, noUpdateTTL, maxSize = 0, maxEntrySize = 0, sizeCalculation, fetchMethod, memoMethod, noDeleteOnFetchRejection, noDeleteOnStaleGet, allowStaleOnFetchRejection, allowStaleOnFetchAbort, ignoreFetchAbort } = options;
37899
+ if (max !== 0 && !isPosInt(max)) {
37900
+ throw new TypeError("max option must be a nonnegative integer");
37901
+ }
37902
+ const UintArray = max ? getUintArray(max) : Array;
37903
+ if (!UintArray) {
37904
+ throw new Error("invalid max value: " + max);
37905
+ }
37906
+ this.#max = max;
37907
+ this.#maxSize = maxSize;
37908
+ this.maxEntrySize = maxEntrySize || this.#maxSize;
37909
+ this.sizeCalculation = sizeCalculation;
37910
+ if (this.sizeCalculation) {
37911
+ if (!this.#maxSize && !this.maxEntrySize) {
37912
+ throw new TypeError("cannot set sizeCalculation without setting maxSize or maxEntrySize");
37913
+ }
37914
+ if (typeof this.sizeCalculation !== "function") {
37915
+ throw new TypeError("sizeCalculation set to non-function");
37916
+ }
37917
+ }
37918
+ if (memoMethod !== void 0 && typeof memoMethod !== "function") {
37919
+ throw new TypeError("memoMethod must be a function if defined");
37920
+ }
37921
+ this.#memoMethod = memoMethod;
37922
+ if (fetchMethod !== void 0 && typeof fetchMethod !== "function") {
37923
+ throw new TypeError("fetchMethod must be a function if specified");
37924
+ }
37925
+ this.#fetchMethod = fetchMethod;
37926
+ this.#hasFetchMethod = !!fetchMethod;
37927
+ this.#keyMap = /* @__PURE__ */ new Map();
37928
+ this.#keyList = new Array(max).fill(void 0);
37929
+ this.#valList = new Array(max).fill(void 0);
37930
+ this.#next = new UintArray(max);
37931
+ this.#prev = new UintArray(max);
37932
+ this.#head = 0;
37933
+ this.#tail = 0;
37934
+ this.#free = Stack.create(max);
37935
+ this.#size = 0;
37936
+ this.#calculatedSize = 0;
37937
+ if (typeof dispose === "function") {
37938
+ this.#dispose = dispose;
37939
+ }
37940
+ if (typeof onInsert === "function") {
37941
+ this.#onInsert = onInsert;
37942
+ }
37943
+ if (typeof disposeAfter === "function") {
37944
+ this.#disposeAfter = disposeAfter;
37945
+ this.#disposed = [];
37946
+ } else {
37947
+ this.#disposeAfter = void 0;
37948
+ this.#disposed = void 0;
37949
+ }
37950
+ this.#hasDispose = !!this.#dispose;
37951
+ this.#hasOnInsert = !!this.#onInsert;
37952
+ this.#hasDisposeAfter = !!this.#disposeAfter;
37953
+ this.noDisposeOnSet = !!noDisposeOnSet;
37954
+ this.noUpdateTTL = !!noUpdateTTL;
37955
+ this.noDeleteOnFetchRejection = !!noDeleteOnFetchRejection;
37956
+ this.allowStaleOnFetchRejection = !!allowStaleOnFetchRejection;
37957
+ this.allowStaleOnFetchAbort = !!allowStaleOnFetchAbort;
37958
+ this.ignoreFetchAbort = !!ignoreFetchAbort;
37959
+ if (this.maxEntrySize !== 0) {
37960
+ if (this.#maxSize !== 0) {
37961
+ if (!isPosInt(this.#maxSize)) {
37962
+ throw new TypeError("maxSize must be a positive integer if specified");
37963
+ }
37964
+ }
37965
+ if (!isPosInt(this.maxEntrySize)) {
37966
+ throw new TypeError("maxEntrySize must be a positive integer if specified");
37967
+ }
37968
+ this.#initializeSizeTracking();
37969
+ }
37970
+ this.allowStale = !!allowStale;
37971
+ this.noDeleteOnStaleGet = !!noDeleteOnStaleGet;
37972
+ this.updateAgeOnGet = !!updateAgeOnGet;
37973
+ this.updateAgeOnHas = !!updateAgeOnHas;
37974
+ this.ttlResolution = isPosInt(ttlResolution) || ttlResolution === 0 ? ttlResolution : 1;
37975
+ this.ttlAutopurge = !!ttlAutopurge;
37976
+ this.ttl = ttl || 0;
37977
+ if (this.ttl) {
37978
+ if (!isPosInt(this.ttl)) {
37979
+ throw new TypeError("ttl must be a positive integer if specified");
37980
+ }
37981
+ this.#initializeTTLTracking();
37982
+ }
37983
+ if (this.#max === 0 && this.ttl === 0 && this.#maxSize === 0) {
37984
+ throw new TypeError("At least one of max, maxSize, or ttl is required");
37985
+ }
37986
+ if (!this.ttlAutopurge && !this.#max && !this.#maxSize) {
37987
+ const code = "LRU_CACHE_UNBOUNDED";
37988
+ if (shouldWarn(code)) {
37989
+ warned.add(code);
37990
+ const msg = "TTL caching without ttlAutopurge, max, or maxSize can result in unbounded memory consumption.";
37991
+ emitWarning(msg, "UnboundedCacheWarning", code, _LRUCache);
37992
+ }
37993
+ }
37994
+ }
37995
+ /**
37996
+ * Return the number of ms left in the item's TTL. If item is not in cache,
37997
+ * returns `0`. Returns `Infinity` if item is in cache without a defined TTL.
37998
+ */
37999
+ getRemainingTTL(key) {
38000
+ return this.#keyMap.has(key) ? Infinity : 0;
38001
+ }
38002
+ #initializeTTLTracking() {
38003
+ const ttls = new ZeroArray(this.#max);
38004
+ const starts = new ZeroArray(this.#max);
38005
+ this.#ttls = ttls;
38006
+ this.#starts = starts;
38007
+ this.#setItemTTL = (index, ttl, start = perf.now()) => {
38008
+ starts[index] = ttl !== 0 ? start : 0;
38009
+ ttls[index] = ttl;
38010
+ if (ttl !== 0 && this.ttlAutopurge) {
38011
+ const t2 = setTimeout(() => {
38012
+ if (this.#isStale(index)) {
38013
+ this.#delete(this.#keyList[index], "expire");
38014
+ }
38015
+ }, ttl + 1);
38016
+ if (t2.unref) {
38017
+ t2.unref();
38018
+ }
38019
+ }
38020
+ };
38021
+ this.#updateItemAge = (index) => {
38022
+ starts[index] = ttls[index] !== 0 ? perf.now() : 0;
38023
+ };
38024
+ this.#statusTTL = (status, index) => {
38025
+ if (ttls[index]) {
38026
+ const ttl = ttls[index];
38027
+ const start = starts[index];
38028
+ if (!ttl || !start)
38029
+ return;
38030
+ status.ttl = ttl;
38031
+ status.start = start;
38032
+ status.now = cachedNow || getNow();
38033
+ const age = status.now - start;
38034
+ status.remainingTTL = ttl - age;
38035
+ }
38036
+ };
38037
+ let cachedNow = 0;
38038
+ const getNow = () => {
38039
+ const n2 = perf.now();
38040
+ if (this.ttlResolution > 0) {
38041
+ cachedNow = n2;
38042
+ const t2 = setTimeout(() => cachedNow = 0, this.ttlResolution);
38043
+ if (t2.unref) {
38044
+ t2.unref();
38045
+ }
38046
+ }
38047
+ return n2;
38048
+ };
38049
+ this.getRemainingTTL = (key) => {
38050
+ const index = this.#keyMap.get(key);
38051
+ if (index === void 0) {
38052
+ return 0;
38053
+ }
38054
+ const ttl = ttls[index];
38055
+ const start = starts[index];
38056
+ if (!ttl || !start) {
38057
+ return Infinity;
38058
+ }
38059
+ const age = (cachedNow || getNow()) - start;
38060
+ return ttl - age;
38061
+ };
38062
+ this.#isStale = (index) => {
38063
+ const s2 = starts[index];
38064
+ const t2 = ttls[index];
38065
+ return !!t2 && !!s2 && (cachedNow || getNow()) - s2 > t2;
38066
+ };
38067
+ }
38068
+ // conditionally set private methods related to TTL
38069
+ #updateItemAge = () => {
38070
+ };
38071
+ #statusTTL = () => {
38072
+ };
38073
+ #setItemTTL = () => {
38074
+ };
38075
+ /* c8 ignore stop */
38076
+ #isStale = () => false;
38077
+ #initializeSizeTracking() {
38078
+ const sizes = new ZeroArray(this.#max);
38079
+ this.#calculatedSize = 0;
38080
+ this.#sizes = sizes;
38081
+ this.#removeItemSize = (index) => {
38082
+ this.#calculatedSize -= sizes[index];
38083
+ sizes[index] = 0;
38084
+ };
38085
+ this.#requireSize = (k2, v2, size, sizeCalculation) => {
38086
+ if (this.#isBackgroundFetch(v2)) {
38087
+ return 0;
38088
+ }
38089
+ if (!isPosInt(size)) {
38090
+ if (sizeCalculation) {
38091
+ if (typeof sizeCalculation !== "function") {
38092
+ throw new TypeError("sizeCalculation must be a function");
38093
+ }
38094
+ size = sizeCalculation(v2, k2);
38095
+ if (!isPosInt(size)) {
38096
+ throw new TypeError("sizeCalculation return invalid (expect positive integer)");
38097
+ }
38098
+ } else {
38099
+ throw new TypeError("invalid size value (must be positive integer). When maxSize or maxEntrySize is used, sizeCalculation or size must be set.");
38100
+ }
38101
+ }
38102
+ return size;
38103
+ };
38104
+ this.#addItemSize = (index, size, status) => {
38105
+ sizes[index] = size;
38106
+ if (this.#maxSize) {
38107
+ const maxSize = this.#maxSize - sizes[index];
38108
+ while (this.#calculatedSize > maxSize) {
38109
+ this.#evict(true);
38110
+ }
38111
+ }
38112
+ this.#calculatedSize += sizes[index];
38113
+ if (status) {
38114
+ status.entrySize = size;
38115
+ status.totalCalculatedSize = this.#calculatedSize;
38116
+ }
38117
+ };
38118
+ }
38119
+ #removeItemSize = (_i) => {
38120
+ };
38121
+ #addItemSize = (_i, _s, _st) => {
38122
+ };
38123
+ #requireSize = (_k, _v, size, sizeCalculation) => {
38124
+ if (size || sizeCalculation) {
38125
+ throw new TypeError("cannot set size without setting maxSize or maxEntrySize on cache");
38126
+ }
38127
+ return 0;
38128
+ };
38129
+ *#indexes({ allowStale = this.allowStale } = {}) {
38130
+ if (this.#size) {
38131
+ for (let i2 = this.#tail; true; ) {
38132
+ if (!this.#isValidIndex(i2)) {
38133
+ break;
38134
+ }
38135
+ if (allowStale || !this.#isStale(i2)) {
38136
+ yield i2;
38137
+ }
38138
+ if (i2 === this.#head) {
38139
+ break;
38140
+ } else {
38141
+ i2 = this.#prev[i2];
38142
+ }
38143
+ }
38144
+ }
38145
+ }
38146
+ *#rindexes({ allowStale = this.allowStale } = {}) {
38147
+ if (this.#size) {
38148
+ for (let i2 = this.#head; true; ) {
38149
+ if (!this.#isValidIndex(i2)) {
38150
+ break;
38151
+ }
38152
+ if (allowStale || !this.#isStale(i2)) {
38153
+ yield i2;
38154
+ }
38155
+ if (i2 === this.#tail) {
38156
+ break;
38157
+ } else {
38158
+ i2 = this.#next[i2];
38159
+ }
38160
+ }
38161
+ }
38162
+ }
38163
+ #isValidIndex(index) {
38164
+ return index !== void 0 && this.#keyMap.get(this.#keyList[index]) === index;
38165
+ }
38166
+ /**
38167
+ * Return a generator yielding `[key, value]` pairs,
38168
+ * in order from most recently used to least recently used.
38169
+ */
38170
+ *entries() {
38171
+ for (const i2 of this.#indexes()) {
38172
+ if (this.#valList[i2] !== void 0 && this.#keyList[i2] !== void 0 && !this.#isBackgroundFetch(this.#valList[i2])) {
38173
+ yield [this.#keyList[i2], this.#valList[i2]];
38174
+ }
38175
+ }
38176
+ }
38177
+ /**
38178
+ * Inverse order version of {@link LRUCache.entries}
38179
+ *
38180
+ * Return a generator yielding `[key, value]` pairs,
38181
+ * in order from least recently used to most recently used.
38182
+ */
38183
+ *rentries() {
38184
+ for (const i2 of this.#rindexes()) {
38185
+ if (this.#valList[i2] !== void 0 && this.#keyList[i2] !== void 0 && !this.#isBackgroundFetch(this.#valList[i2])) {
38186
+ yield [this.#keyList[i2], this.#valList[i2]];
38187
+ }
38188
+ }
38189
+ }
38190
+ /**
38191
+ * Return a generator yielding the keys in the cache,
38192
+ * in order from most recently used to least recently used.
38193
+ */
38194
+ *keys() {
38195
+ for (const i2 of this.#indexes()) {
38196
+ const k2 = this.#keyList[i2];
38197
+ if (k2 !== void 0 && !this.#isBackgroundFetch(this.#valList[i2])) {
38198
+ yield k2;
38199
+ }
38200
+ }
38201
+ }
38202
+ /**
38203
+ * Inverse order version of {@link LRUCache.keys}
38204
+ *
38205
+ * Return a generator yielding the keys in the cache,
38206
+ * in order from least recently used to most recently used.
38207
+ */
38208
+ *rkeys() {
38209
+ for (const i2 of this.#rindexes()) {
38210
+ const k2 = this.#keyList[i2];
38211
+ if (k2 !== void 0 && !this.#isBackgroundFetch(this.#valList[i2])) {
38212
+ yield k2;
38213
+ }
38214
+ }
38215
+ }
38216
+ /**
38217
+ * Return a generator yielding the values in the cache,
38218
+ * in order from most recently used to least recently used.
38219
+ */
38220
+ *values() {
38221
+ for (const i2 of this.#indexes()) {
38222
+ const v2 = this.#valList[i2];
38223
+ if (v2 !== void 0 && !this.#isBackgroundFetch(this.#valList[i2])) {
38224
+ yield this.#valList[i2];
38225
+ }
38226
+ }
38227
+ }
38228
+ /**
38229
+ * Inverse order version of {@link LRUCache.values}
38230
+ *
38231
+ * Return a generator yielding the values in the cache,
38232
+ * in order from least recently used to most recently used.
38233
+ */
38234
+ *rvalues() {
38235
+ for (const i2 of this.#rindexes()) {
38236
+ const v2 = this.#valList[i2];
38237
+ if (v2 !== void 0 && !this.#isBackgroundFetch(this.#valList[i2])) {
38238
+ yield this.#valList[i2];
38239
+ }
38240
+ }
38241
+ }
38242
+ /**
38243
+ * Iterating over the cache itself yields the same results as
38244
+ * {@link LRUCache.entries}
38245
+ */
38246
+ [Symbol.iterator]() {
38247
+ return this.entries();
38248
+ }
38249
+ /**
38250
+ * A String value that is used in the creation of the default string
38251
+ * description of an object. Called by the built-in method
38252
+ * `Object.prototype.toString`.
38253
+ */
38254
+ [Symbol.toStringTag] = "LRUCache";
38255
+ /**
38256
+ * Find a value for which the supplied fn method returns a truthy value,
38257
+ * similar to `Array.find()`. fn is called as `fn(value, key, cache)`.
38258
+ */
38259
+ find(fn, getOptions = {}) {
38260
+ for (const i2 of this.#indexes()) {
38261
+ const v2 = this.#valList[i2];
38262
+ const value = this.#isBackgroundFetch(v2) ? v2.__staleWhileFetching : v2;
38263
+ if (value === void 0)
38264
+ continue;
38265
+ if (fn(value, this.#keyList[i2], this)) {
38266
+ return this.get(this.#keyList[i2], getOptions);
38267
+ }
38268
+ }
38269
+ }
38270
+ /**
38271
+ * Call the supplied function on each item in the cache, in order from most
38272
+ * recently used to least recently used.
38273
+ *
38274
+ * `fn` is called as `fn(value, key, cache)`.
38275
+ *
38276
+ * If `thisp` is provided, function will be called in the `this`-context of
38277
+ * the provided object, or the cache if no `thisp` object is provided.
38278
+ *
38279
+ * Does not update age or recenty of use, or iterate over stale values.
38280
+ */
38281
+ forEach(fn, thisp = this) {
38282
+ for (const i2 of this.#indexes()) {
38283
+ const v2 = this.#valList[i2];
38284
+ const value = this.#isBackgroundFetch(v2) ? v2.__staleWhileFetching : v2;
38285
+ if (value === void 0)
38286
+ continue;
38287
+ fn.call(thisp, value, this.#keyList[i2], this);
38288
+ }
38289
+ }
38290
+ /**
38291
+ * The same as {@link LRUCache.forEach} but items are iterated over in
38292
+ * reverse order. (ie, less recently used items are iterated over first.)
38293
+ */
38294
+ rforEach(fn, thisp = this) {
38295
+ for (const i2 of this.#rindexes()) {
38296
+ const v2 = this.#valList[i2];
38297
+ const value = this.#isBackgroundFetch(v2) ? v2.__staleWhileFetching : v2;
38298
+ if (value === void 0)
38299
+ continue;
38300
+ fn.call(thisp, value, this.#keyList[i2], this);
38301
+ }
38302
+ }
38303
+ /**
38304
+ * Delete any stale entries. Returns true if anything was removed,
38305
+ * false otherwise.
38306
+ */
38307
+ purgeStale() {
38308
+ let deleted = false;
38309
+ for (const i2 of this.#rindexes({ allowStale: true })) {
38310
+ if (this.#isStale(i2)) {
38311
+ this.#delete(this.#keyList[i2], "expire");
38312
+ deleted = true;
38313
+ }
38314
+ }
38315
+ return deleted;
38316
+ }
38317
+ /**
38318
+ * Get the extended info about a given entry, to get its value, size, and
38319
+ * TTL info simultaneously. Returns `undefined` if the key is not present.
38320
+ *
38321
+ * Unlike {@link LRUCache#dump}, which is designed to be portable and survive
38322
+ * serialization, the `start` value is always the current timestamp, and the
38323
+ * `ttl` is a calculated remaining time to live (negative if expired).
38324
+ *
38325
+ * Always returns stale values, if their info is found in the cache, so be
38326
+ * sure to check for expirations (ie, a negative {@link LRUCache.Entry#ttl})
38327
+ * if relevant.
38328
+ */
38329
+ info(key) {
38330
+ const i2 = this.#keyMap.get(key);
38331
+ if (i2 === void 0)
38332
+ return void 0;
38333
+ const v2 = this.#valList[i2];
38334
+ const value = this.#isBackgroundFetch(v2) ? v2.__staleWhileFetching : v2;
38335
+ if (value === void 0)
38336
+ return void 0;
38337
+ const entry = { value };
38338
+ if (this.#ttls && this.#starts) {
38339
+ const ttl = this.#ttls[i2];
38340
+ const start = this.#starts[i2];
38341
+ if (ttl && start) {
38342
+ const remain = ttl - (perf.now() - start);
38343
+ entry.ttl = remain;
38344
+ entry.start = Date.now();
38345
+ }
38346
+ }
38347
+ if (this.#sizes) {
38348
+ entry.size = this.#sizes[i2];
38349
+ }
38350
+ return entry;
38351
+ }
38352
+ /**
38353
+ * Return an array of [key, {@link LRUCache.Entry}] tuples which can be
38354
+ * passed to {@link LRUCache#load}.
38355
+ *
38356
+ * The `start` fields are calculated relative to a portable `Date.now()`
38357
+ * timestamp, even if `performance.now()` is available.
38358
+ *
38359
+ * Stale entries are always included in the `dump`, even if
38360
+ * {@link LRUCache.OptionsBase.allowStale} is false.
38361
+ *
38362
+ * Note: this returns an actual array, not a generator, so it can be more
38363
+ * easily passed around.
38364
+ */
38365
+ dump() {
38366
+ const arr = [];
38367
+ for (const i2 of this.#indexes({ allowStale: true })) {
38368
+ const key = this.#keyList[i2];
38369
+ const v2 = this.#valList[i2];
38370
+ const value = this.#isBackgroundFetch(v2) ? v2.__staleWhileFetching : v2;
38371
+ if (value === void 0 || key === void 0)
38372
+ continue;
38373
+ const entry = { value };
38374
+ if (this.#ttls && this.#starts) {
38375
+ entry.ttl = this.#ttls[i2];
38376
+ const age = perf.now() - this.#starts[i2];
38377
+ entry.start = Math.floor(Date.now() - age);
38378
+ }
38379
+ if (this.#sizes) {
38380
+ entry.size = this.#sizes[i2];
38381
+ }
38382
+ arr.unshift([key, entry]);
38383
+ }
38384
+ return arr;
38385
+ }
38386
+ /**
38387
+ * Reset the cache and load in the items in entries in the order listed.
38388
+ *
38389
+ * The shape of the resulting cache may be different if the same options are
38390
+ * not used in both caches.
38391
+ *
38392
+ * The `start` fields are assumed to be calculated relative to a portable
38393
+ * `Date.now()` timestamp, even if `performance.now()` is available.
38394
+ */
38395
+ load(arr) {
38396
+ this.clear();
38397
+ for (const [key, entry] of arr) {
38398
+ if (entry.start) {
38399
+ const age = Date.now() - entry.start;
38400
+ entry.start = perf.now() - age;
38401
+ }
38402
+ this.set(key, entry.value, entry);
38403
+ }
38404
+ }
38405
+ /**
38406
+ * Add a value to the cache.
38407
+ *
38408
+ * Note: if `undefined` is specified as a value, this is an alias for
38409
+ * {@link LRUCache#delete}
38410
+ *
38411
+ * Fields on the {@link LRUCache.SetOptions} options param will override
38412
+ * their corresponding values in the constructor options for the scope
38413
+ * of this single `set()` operation.
38414
+ *
38415
+ * If `start` is provided, then that will set the effective start
38416
+ * time for the TTL calculation. Note that this must be a previous
38417
+ * value of `performance.now()` if supported, or a previous value of
38418
+ * `Date.now()` if not.
38419
+ *
38420
+ * Options object may also include `size`, which will prevent
38421
+ * calling the `sizeCalculation` function and just use the specified
38422
+ * number if it is a positive integer, and `noDisposeOnSet` which
38423
+ * will prevent calling a `dispose` function in the case of
38424
+ * overwrites.
38425
+ *
38426
+ * If the `size` (or return value of `sizeCalculation`) for a given
38427
+ * entry is greater than `maxEntrySize`, then the item will not be
38428
+ * added to the cache.
38429
+ *
38430
+ * Will update the recency of the entry.
38431
+ *
38432
+ * If the value is `undefined`, then this is an alias for
38433
+ * `cache.delete(key)`. `undefined` is never stored in the cache.
38434
+ */
38435
+ set(k2, v2, setOptions = {}) {
38436
+ if (v2 === void 0) {
38437
+ this.delete(k2);
38438
+ return this;
38439
+ }
38440
+ const { ttl = this.ttl, start, noDisposeOnSet = this.noDisposeOnSet, sizeCalculation = this.sizeCalculation, status } = setOptions;
38441
+ let { noUpdateTTL = this.noUpdateTTL } = setOptions;
38442
+ const size = this.#requireSize(k2, v2, setOptions.size || 0, sizeCalculation);
38443
+ if (this.maxEntrySize && size > this.maxEntrySize) {
38444
+ if (status) {
38445
+ status.set = "miss";
38446
+ status.maxEntrySizeExceeded = true;
38447
+ }
38448
+ this.#delete(k2, "set");
38449
+ return this;
38450
+ }
38451
+ let index = this.#size === 0 ? void 0 : this.#keyMap.get(k2);
38452
+ if (index === void 0) {
38453
+ index = this.#size === 0 ? this.#tail : this.#free.length !== 0 ? this.#free.pop() : this.#size === this.#max ? this.#evict(false) : this.#size;
38454
+ this.#keyList[index] = k2;
38455
+ this.#valList[index] = v2;
38456
+ this.#keyMap.set(k2, index);
38457
+ this.#next[this.#tail] = index;
38458
+ this.#prev[index] = this.#tail;
38459
+ this.#tail = index;
38460
+ this.#size++;
38461
+ this.#addItemSize(index, size, status);
38462
+ if (status)
38463
+ status.set = "add";
38464
+ noUpdateTTL = false;
38465
+ if (this.#hasOnInsert) {
38466
+ this.#onInsert?.(v2, k2, "add");
38467
+ }
38468
+ } else {
38469
+ this.#moveToTail(index);
38470
+ const oldVal = this.#valList[index];
38471
+ if (v2 !== oldVal) {
38472
+ if (this.#hasFetchMethod && this.#isBackgroundFetch(oldVal)) {
38473
+ oldVal.__abortController.abort(new Error("replaced"));
38474
+ const { __staleWhileFetching: s2 } = oldVal;
38475
+ if (s2 !== void 0 && !noDisposeOnSet) {
38476
+ if (this.#hasDispose) {
38477
+ this.#dispose?.(s2, k2, "set");
38478
+ }
38479
+ if (this.#hasDisposeAfter) {
38480
+ this.#disposed?.push([s2, k2, "set"]);
38481
+ }
38482
+ }
38483
+ } else if (!noDisposeOnSet) {
38484
+ if (this.#hasDispose) {
38485
+ this.#dispose?.(oldVal, k2, "set");
38486
+ }
38487
+ if (this.#hasDisposeAfter) {
38488
+ this.#disposed?.push([oldVal, k2, "set"]);
38489
+ }
38490
+ }
38491
+ this.#removeItemSize(index);
38492
+ this.#addItemSize(index, size, status);
38493
+ this.#valList[index] = v2;
38494
+ if (status) {
38495
+ status.set = "replace";
38496
+ const oldValue = oldVal && this.#isBackgroundFetch(oldVal) ? oldVal.__staleWhileFetching : oldVal;
38497
+ if (oldValue !== void 0)
38498
+ status.oldValue = oldValue;
38499
+ }
38500
+ } else if (status) {
38501
+ status.set = "update";
38502
+ }
38503
+ if (this.#hasOnInsert) {
38504
+ this.onInsert?.(v2, k2, v2 === oldVal ? "update" : "replace");
38505
+ }
38506
+ }
38507
+ if (ttl !== 0 && !this.#ttls) {
38508
+ this.#initializeTTLTracking();
38509
+ }
38510
+ if (this.#ttls) {
38511
+ if (!noUpdateTTL) {
38512
+ this.#setItemTTL(index, ttl, start);
38513
+ }
38514
+ if (status)
38515
+ this.#statusTTL(status, index);
38516
+ }
38517
+ if (!noDisposeOnSet && this.#hasDisposeAfter && this.#disposed) {
38518
+ const dt2 = this.#disposed;
38519
+ let task;
38520
+ while (task = dt2?.shift()) {
38521
+ this.#disposeAfter?.(...task);
38522
+ }
38523
+ }
38524
+ return this;
38525
+ }
38526
+ /**
38527
+ * Evict the least recently used item, returning its value or
38528
+ * `undefined` if cache is empty.
38529
+ */
38530
+ pop() {
38531
+ try {
38532
+ while (this.#size) {
38533
+ const val = this.#valList[this.#head];
38534
+ this.#evict(true);
38535
+ if (this.#isBackgroundFetch(val)) {
38536
+ if (val.__staleWhileFetching) {
38537
+ return val.__staleWhileFetching;
38538
+ }
38539
+ } else if (val !== void 0) {
38540
+ return val;
38541
+ }
38542
+ }
38543
+ } finally {
38544
+ if (this.#hasDisposeAfter && this.#disposed) {
38545
+ const dt2 = this.#disposed;
38546
+ let task;
38547
+ while (task = dt2?.shift()) {
38548
+ this.#disposeAfter?.(...task);
38549
+ }
38550
+ }
38551
+ }
38552
+ }
38553
+ #evict(free) {
38554
+ const head = this.#head;
38555
+ const k2 = this.#keyList[head];
38556
+ const v2 = this.#valList[head];
38557
+ if (this.#hasFetchMethod && this.#isBackgroundFetch(v2)) {
38558
+ v2.__abortController.abort(new Error("evicted"));
38559
+ } else if (this.#hasDispose || this.#hasDisposeAfter) {
38560
+ if (this.#hasDispose) {
38561
+ this.#dispose?.(v2, k2, "evict");
38562
+ }
38563
+ if (this.#hasDisposeAfter) {
38564
+ this.#disposed?.push([v2, k2, "evict"]);
38565
+ }
38566
+ }
38567
+ this.#removeItemSize(head);
38568
+ if (free) {
38569
+ this.#keyList[head] = void 0;
38570
+ this.#valList[head] = void 0;
38571
+ this.#free.push(head);
38572
+ }
38573
+ if (this.#size === 1) {
38574
+ this.#head = this.#tail = 0;
38575
+ this.#free.length = 0;
38576
+ } else {
38577
+ this.#head = this.#next[head];
38578
+ }
38579
+ this.#keyMap.delete(k2);
38580
+ this.#size--;
38581
+ return head;
38582
+ }
38583
+ /**
38584
+ * Check if a key is in the cache, without updating the recency of use.
38585
+ * Will return false if the item is stale, even though it is technically
38586
+ * in the cache.
38587
+ *
38588
+ * Check if a key is in the cache, without updating the recency of
38589
+ * use. Age is updated if {@link LRUCache.OptionsBase.updateAgeOnHas} is set
38590
+ * to `true` in either the options or the constructor.
38591
+ *
38592
+ * Will return `false` if the item is stale, even though it is technically in
38593
+ * the cache. The difference can be determined (if it matters) by using a
38594
+ * `status` argument, and inspecting the `has` field.
38595
+ *
38596
+ * Will not update item age unless
38597
+ * {@link LRUCache.OptionsBase.updateAgeOnHas} is set.
38598
+ */
38599
+ has(k2, hasOptions = {}) {
38600
+ const { updateAgeOnHas = this.updateAgeOnHas, status } = hasOptions;
38601
+ const index = this.#keyMap.get(k2);
38602
+ if (index !== void 0) {
38603
+ const v2 = this.#valList[index];
38604
+ if (this.#isBackgroundFetch(v2) && v2.__staleWhileFetching === void 0) {
38605
+ return false;
38606
+ }
38607
+ if (!this.#isStale(index)) {
38608
+ if (updateAgeOnHas) {
38609
+ this.#updateItemAge(index);
38610
+ }
38611
+ if (status) {
38612
+ status.has = "hit";
38613
+ this.#statusTTL(status, index);
38614
+ }
38615
+ return true;
38616
+ } else if (status) {
38617
+ status.has = "stale";
38618
+ this.#statusTTL(status, index);
38619
+ }
38620
+ } else if (status) {
38621
+ status.has = "miss";
38622
+ }
38623
+ return false;
38624
+ }
38625
+ /**
38626
+ * Like {@link LRUCache#get} but doesn't update recency or delete stale
38627
+ * items.
38628
+ *
38629
+ * Returns `undefined` if the item is stale, unless
38630
+ * {@link LRUCache.OptionsBase.allowStale} is set.
38631
+ */
38632
+ peek(k2, peekOptions = {}) {
38633
+ const { allowStale = this.allowStale } = peekOptions;
38634
+ const index = this.#keyMap.get(k2);
38635
+ if (index === void 0 || !allowStale && this.#isStale(index)) {
38636
+ return;
38637
+ }
38638
+ const v2 = this.#valList[index];
38639
+ return this.#isBackgroundFetch(v2) ? v2.__staleWhileFetching : v2;
38640
+ }
38641
+ #backgroundFetch(k2, index, options, context) {
38642
+ const v2 = index === void 0 ? void 0 : this.#valList[index];
38643
+ if (this.#isBackgroundFetch(v2)) {
38644
+ return v2;
38645
+ }
38646
+ const ac = new AC();
38647
+ const { signal } = options;
38648
+ signal?.addEventListener("abort", () => ac.abort(signal.reason), {
38649
+ signal: ac.signal
38650
+ });
38651
+ const fetchOpts = {
38652
+ signal: ac.signal,
38653
+ options,
38654
+ context
38655
+ };
38656
+ const cb = (v3, updateCache = false) => {
38657
+ const { aborted } = ac.signal;
38658
+ const ignoreAbort = options.ignoreFetchAbort && v3 !== void 0;
38659
+ if (options.status) {
38660
+ if (aborted && !updateCache) {
38661
+ options.status.fetchAborted = true;
38662
+ options.status.fetchError = ac.signal.reason;
38663
+ if (ignoreAbort)
38664
+ options.status.fetchAbortIgnored = true;
38665
+ } else {
38666
+ options.status.fetchResolved = true;
38667
+ }
38668
+ }
38669
+ if (aborted && !ignoreAbort && !updateCache) {
38670
+ return fetchFail(ac.signal.reason);
38671
+ }
38672
+ const bf2 = p2;
38673
+ if (this.#valList[index] === p2) {
38674
+ if (v3 === void 0) {
38675
+ if (bf2.__staleWhileFetching) {
38676
+ this.#valList[index] = bf2.__staleWhileFetching;
38677
+ } else {
38678
+ this.#delete(k2, "fetch");
38679
+ }
38680
+ } else {
38681
+ if (options.status)
38682
+ options.status.fetchUpdated = true;
38683
+ this.set(k2, v3, fetchOpts.options);
38684
+ }
38685
+ }
38686
+ return v3;
38687
+ };
38688
+ const eb = (er2) => {
38689
+ if (options.status) {
38690
+ options.status.fetchRejected = true;
38691
+ options.status.fetchError = er2;
38692
+ }
38693
+ return fetchFail(er2);
38694
+ };
38695
+ const fetchFail = (er2) => {
38696
+ const { aborted } = ac.signal;
38697
+ const allowStaleAborted = aborted && options.allowStaleOnFetchAbort;
38698
+ const allowStale = allowStaleAborted || options.allowStaleOnFetchRejection;
38699
+ const noDelete = allowStale || options.noDeleteOnFetchRejection;
38700
+ const bf2 = p2;
38701
+ if (this.#valList[index] === p2) {
38702
+ const del = !noDelete || bf2.__staleWhileFetching === void 0;
38703
+ if (del) {
38704
+ this.#delete(k2, "fetch");
38705
+ } else if (!allowStaleAborted) {
38706
+ this.#valList[index] = bf2.__staleWhileFetching;
38707
+ }
38708
+ }
38709
+ if (allowStale) {
38710
+ if (options.status && bf2.__staleWhileFetching !== void 0) {
38711
+ options.status.returnedStale = true;
38712
+ }
38713
+ return bf2.__staleWhileFetching;
38714
+ } else if (bf2.__returned === bf2) {
38715
+ throw er2;
38716
+ }
38717
+ };
38718
+ const pcall = (res, rej) => {
38719
+ const fmp = this.#fetchMethod?.(k2, v2, fetchOpts);
38720
+ if (fmp && fmp instanceof Promise) {
38721
+ fmp.then((v3) => res(v3 === void 0 ? void 0 : v3), rej);
38722
+ }
38723
+ ac.signal.addEventListener("abort", () => {
38724
+ if (!options.ignoreFetchAbort || options.allowStaleOnFetchAbort) {
38725
+ res(void 0);
38726
+ if (options.allowStaleOnFetchAbort) {
38727
+ res = (v3) => cb(v3, true);
38728
+ }
38729
+ }
38730
+ });
38731
+ };
38732
+ if (options.status)
38733
+ options.status.fetchDispatched = true;
38734
+ const p2 = new Promise(pcall).then(cb, eb);
38735
+ const bf = Object.assign(p2, {
38736
+ __abortController: ac,
38737
+ __staleWhileFetching: v2,
38738
+ __returned: void 0
38739
+ });
38740
+ if (index === void 0) {
38741
+ this.set(k2, bf, { ...fetchOpts.options, status: void 0 });
38742
+ index = this.#keyMap.get(k2);
38743
+ } else {
38744
+ this.#valList[index] = bf;
38745
+ }
38746
+ return bf;
38747
+ }
38748
+ #isBackgroundFetch(p2) {
38749
+ if (!this.#hasFetchMethod)
38750
+ return false;
38751
+ const b2 = p2;
38752
+ return !!b2 && b2 instanceof Promise && b2.hasOwnProperty("__staleWhileFetching") && b2.__abortController instanceof AC;
38753
+ }
38754
+ async fetch(k2, fetchOptions = {}) {
38755
+ const {
38756
+ // get options
38757
+ allowStale = this.allowStale,
38758
+ updateAgeOnGet = this.updateAgeOnGet,
38759
+ noDeleteOnStaleGet = this.noDeleteOnStaleGet,
38760
+ // set options
38761
+ ttl = this.ttl,
38762
+ noDisposeOnSet = this.noDisposeOnSet,
38763
+ size = 0,
38764
+ sizeCalculation = this.sizeCalculation,
38765
+ noUpdateTTL = this.noUpdateTTL,
38766
+ // fetch exclusive options
38767
+ noDeleteOnFetchRejection = this.noDeleteOnFetchRejection,
38768
+ allowStaleOnFetchRejection = this.allowStaleOnFetchRejection,
38769
+ ignoreFetchAbort = this.ignoreFetchAbort,
38770
+ allowStaleOnFetchAbort = this.allowStaleOnFetchAbort,
38771
+ context,
38772
+ forceRefresh = false,
38773
+ status,
38774
+ signal
38775
+ } = fetchOptions;
38776
+ if (!this.#hasFetchMethod) {
38777
+ if (status)
38778
+ status.fetch = "get";
38779
+ return this.get(k2, {
38780
+ allowStale,
38781
+ updateAgeOnGet,
38782
+ noDeleteOnStaleGet,
38783
+ status
38784
+ });
38785
+ }
38786
+ const options = {
38787
+ allowStale,
38788
+ updateAgeOnGet,
38789
+ noDeleteOnStaleGet,
38790
+ ttl,
38791
+ noDisposeOnSet,
38792
+ size,
38793
+ sizeCalculation,
38794
+ noUpdateTTL,
38795
+ noDeleteOnFetchRejection,
38796
+ allowStaleOnFetchRejection,
38797
+ allowStaleOnFetchAbort,
38798
+ ignoreFetchAbort,
38799
+ status,
38800
+ signal
38801
+ };
38802
+ let index = this.#keyMap.get(k2);
38803
+ if (index === void 0) {
38804
+ if (status)
38805
+ status.fetch = "miss";
38806
+ const p2 = this.#backgroundFetch(k2, index, options, context);
38807
+ return p2.__returned = p2;
38808
+ } else {
38809
+ const v2 = this.#valList[index];
38810
+ if (this.#isBackgroundFetch(v2)) {
38811
+ const stale = allowStale && v2.__staleWhileFetching !== void 0;
38812
+ if (status) {
38813
+ status.fetch = "inflight";
38814
+ if (stale)
38815
+ status.returnedStale = true;
38816
+ }
38817
+ return stale ? v2.__staleWhileFetching : v2.__returned = v2;
38818
+ }
38819
+ const isStale = this.#isStale(index);
38820
+ if (!forceRefresh && !isStale) {
38821
+ if (status)
38822
+ status.fetch = "hit";
38823
+ this.#moveToTail(index);
38824
+ if (updateAgeOnGet) {
38825
+ this.#updateItemAge(index);
38826
+ }
38827
+ if (status)
38828
+ this.#statusTTL(status, index);
38829
+ return v2;
38830
+ }
38831
+ const p2 = this.#backgroundFetch(k2, index, options, context);
38832
+ const hasStale = p2.__staleWhileFetching !== void 0;
38833
+ const staleVal = hasStale && allowStale;
38834
+ if (status) {
38835
+ status.fetch = isStale ? "stale" : "refresh";
38836
+ if (staleVal && isStale)
38837
+ status.returnedStale = true;
38838
+ }
38839
+ return staleVal ? p2.__staleWhileFetching : p2.__returned = p2;
38840
+ }
38841
+ }
38842
+ async forceFetch(k2, fetchOptions = {}) {
38843
+ const v2 = await this.fetch(k2, fetchOptions);
38844
+ if (v2 === void 0)
38845
+ throw new Error("fetch() returned undefined");
38846
+ return v2;
38847
+ }
38848
+ memo(k2, memoOptions = {}) {
38849
+ const memoMethod = this.#memoMethod;
38850
+ if (!memoMethod) {
38851
+ throw new Error("no memoMethod provided to constructor");
38852
+ }
38853
+ const { context, forceRefresh, ...options } = memoOptions;
38854
+ const v2 = this.get(k2, options);
38855
+ if (!forceRefresh && v2 !== void 0)
38856
+ return v2;
38857
+ const vv = memoMethod(k2, v2, {
38858
+ options,
38859
+ context
38860
+ });
38861
+ this.set(k2, vv, options);
38862
+ return vv;
38863
+ }
38864
+ /**
38865
+ * Return a value from the cache. Will update the recency of the cache
38866
+ * entry found.
38867
+ *
38868
+ * If the key is not found, get() will return `undefined`.
38869
+ */
38870
+ get(k2, getOptions = {}) {
38871
+ const { allowStale = this.allowStale, updateAgeOnGet = this.updateAgeOnGet, noDeleteOnStaleGet = this.noDeleteOnStaleGet, status } = getOptions;
38872
+ const index = this.#keyMap.get(k2);
38873
+ if (index !== void 0) {
38874
+ const value = this.#valList[index];
38875
+ const fetching = this.#isBackgroundFetch(value);
38876
+ if (status)
38877
+ this.#statusTTL(status, index);
38878
+ if (this.#isStale(index)) {
38879
+ if (status)
38880
+ status.get = "stale";
38881
+ if (!fetching) {
38882
+ if (!noDeleteOnStaleGet) {
38883
+ this.#delete(k2, "expire");
38884
+ }
38885
+ if (status && allowStale)
38886
+ status.returnedStale = true;
38887
+ return allowStale ? value : void 0;
38888
+ } else {
38889
+ if (status && allowStale && value.__staleWhileFetching !== void 0) {
38890
+ status.returnedStale = true;
38891
+ }
38892
+ return allowStale ? value.__staleWhileFetching : void 0;
38893
+ }
38894
+ } else {
38895
+ if (status)
38896
+ status.get = "hit";
38897
+ if (fetching) {
38898
+ return value.__staleWhileFetching;
38899
+ }
38900
+ this.#moveToTail(index);
38901
+ if (updateAgeOnGet) {
38902
+ this.#updateItemAge(index);
38903
+ }
38904
+ return value;
38905
+ }
38906
+ } else if (status) {
38907
+ status.get = "miss";
38908
+ }
38909
+ }
38910
+ #connect(p2, n2) {
38911
+ this.#prev[n2] = p2;
38912
+ this.#next[p2] = n2;
38913
+ }
38914
+ #moveToTail(index) {
38915
+ if (index !== this.#tail) {
38916
+ if (index === this.#head) {
38917
+ this.#head = this.#next[index];
38918
+ } else {
38919
+ this.#connect(this.#prev[index], this.#next[index]);
38920
+ }
38921
+ this.#connect(this.#tail, index);
38922
+ this.#tail = index;
38923
+ }
38924
+ }
38925
+ /**
38926
+ * Deletes a key out of the cache.
38927
+ *
38928
+ * Returns true if the key was deleted, false otherwise.
38929
+ */
38930
+ delete(k2) {
38931
+ return this.#delete(k2, "delete");
38932
+ }
38933
+ #delete(k2, reason) {
38934
+ let deleted = false;
38935
+ if (this.#size !== 0) {
38936
+ const index = this.#keyMap.get(k2);
38937
+ if (index !== void 0) {
38938
+ deleted = true;
38939
+ if (this.#size === 1) {
38940
+ this.#clear(reason);
38941
+ } else {
38942
+ this.#removeItemSize(index);
38943
+ const v2 = this.#valList[index];
38944
+ if (this.#isBackgroundFetch(v2)) {
38945
+ v2.__abortController.abort(new Error("deleted"));
38946
+ } else if (this.#hasDispose || this.#hasDisposeAfter) {
38947
+ if (this.#hasDispose) {
38948
+ this.#dispose?.(v2, k2, reason);
38949
+ }
38950
+ if (this.#hasDisposeAfter) {
38951
+ this.#disposed?.push([v2, k2, reason]);
38952
+ }
38953
+ }
38954
+ this.#keyMap.delete(k2);
38955
+ this.#keyList[index] = void 0;
38956
+ this.#valList[index] = void 0;
38957
+ if (index === this.#tail) {
38958
+ this.#tail = this.#prev[index];
38959
+ } else if (index === this.#head) {
38960
+ this.#head = this.#next[index];
38961
+ } else {
38962
+ const pi = this.#prev[index];
38963
+ this.#next[pi] = this.#next[index];
38964
+ const ni = this.#next[index];
38965
+ this.#prev[ni] = this.#prev[index];
38966
+ }
38967
+ this.#size--;
38968
+ this.#free.push(index);
38969
+ }
38970
+ }
38971
+ }
38972
+ if (this.#hasDisposeAfter && this.#disposed?.length) {
38973
+ const dt2 = this.#disposed;
38974
+ let task;
38975
+ while (task = dt2?.shift()) {
38976
+ this.#disposeAfter?.(...task);
38977
+ }
38978
+ }
38979
+ return deleted;
38980
+ }
38981
+ /**
38982
+ * Clear the cache entirely, throwing away all values.
38983
+ */
38984
+ clear() {
38985
+ return this.#clear("delete");
38986
+ }
38987
+ #clear(reason) {
38988
+ for (const index of this.#rindexes({ allowStale: true })) {
38989
+ const v2 = this.#valList[index];
38990
+ if (this.#isBackgroundFetch(v2)) {
38991
+ v2.__abortController.abort(new Error("deleted"));
38992
+ } else {
38993
+ const k2 = this.#keyList[index];
38994
+ if (this.#hasDispose) {
38995
+ this.#dispose?.(v2, k2, reason);
38996
+ }
38997
+ if (this.#hasDisposeAfter) {
38998
+ this.#disposed?.push([v2, k2, reason]);
38999
+ }
39000
+ }
39001
+ }
39002
+ this.#keyMap.clear();
39003
+ this.#valList.fill(void 0);
39004
+ this.#keyList.fill(void 0);
39005
+ if (this.#ttls && this.#starts) {
39006
+ this.#ttls.fill(0);
39007
+ this.#starts.fill(0);
39008
+ }
39009
+ if (this.#sizes) {
39010
+ this.#sizes.fill(0);
39011
+ }
39012
+ this.#head = 0;
39013
+ this.#tail = 0;
39014
+ this.#free.length = 0;
39015
+ this.#calculatedSize = 0;
39016
+ this.#size = 0;
39017
+ if (this.#hasDisposeAfter && this.#disposed) {
39018
+ const dt2 = this.#disposed;
39019
+ let task;
39020
+ while (task = dt2?.shift()) {
39021
+ this.#disposeAfter?.(...task);
39022
+ }
39023
+ }
39024
+ }
39025
+ };
39026
+
37105
39027
  // src/index.ts
37106
39028
  async function initializeClaudeConfig() {
37107
39029
  const homeDir = process.env.HOME;
@@ -37123,14 +39045,56 @@ async function initializeClaudeConfig() {
37123
39045
  }
37124
39046
  }
37125
39047
  async function run(options = {}) {
37126
- const port = options.port || 3456;
37127
39048
  if (isServiceRunning()) {
37128
39049
  console.log("\u2705 Service is already running in the background.");
37129
39050
  return;
37130
39051
  }
37131
39052
  await initializeClaudeConfig();
37132
39053
  await initDir();
37133
- await initConfig();
39054
+ const config = await initConfig();
39055
+ const Providers = /* @__PURE__ */ new Map();
39056
+ const providerCache = new LRUCache({
39057
+ max: 10,
39058
+ ttl: 2 * 60 * 60 * 1e3
39059
+ });
39060
+ function getProviderInstance(providerName) {
39061
+ const provider = Providers.get(providerName);
39062
+ if (provider === void 0) {
39063
+ throw new Error(`Provider ${providerName} not found`);
39064
+ }
39065
+ let openai = providerCache.get(provider.name);
39066
+ if (!openai) {
39067
+ openai = new openai_default({
39068
+ baseURL: provider.api_base_url,
39069
+ apiKey: provider.api_key,
39070
+ ...getOpenAICommonOptions()
39071
+ });
39072
+ providerCache.set(provider.name, openai);
39073
+ }
39074
+ return openai;
39075
+ }
39076
+ if (Array.isArray(config.Providers)) {
39077
+ config.Providers.forEach((provider) => {
39078
+ try {
39079
+ Providers.set(provider.name, provider);
39080
+ } catch (error) {
39081
+ console.error("Failed to parse model provider:", error);
39082
+ }
39083
+ });
39084
+ }
39085
+ if (config.OPENAI_API_KEY && config.OPENAI_BASE_URL && config.OPENAI_MODEL) {
39086
+ const defaultProvider = {
39087
+ name: "default",
39088
+ api_base_url: config.OPENAI_BASE_URL,
39089
+ api_key: config.OPENAI_API_KEY,
39090
+ models: [config.OPENAI_MODEL]
39091
+ };
39092
+ Providers.set("default", defaultProvider);
39093
+ } else if (Providers.size > 0) {
39094
+ const defaultProvider = Providers.values().next().value;
39095
+ Providers.set("default", defaultProvider);
39096
+ }
39097
+ const port = options.port || 3456;
37134
39098
  savePid(process.pid);
37135
39099
  process.on("SIGINT", () => {
37136
39100
  console.log("Received SIGINT, cleaning up...");
@@ -37142,20 +39106,27 @@ async function run(options = {}) {
37142
39106
  process.exit(0);
37143
39107
  });
37144
39108
  const servicePort = process.env.SERVICE_PORT ? parseInt(process.env.SERVICE_PORT) : port;
37145
- const server = createServer(servicePort);
37146
- server.useMiddleware(formatRequest);
37147
- server.useMiddleware(rewriteBody);
37148
- const openai = new openai_default({
37149
- apiKey: process.env.OPENAI_API_KEY,
37150
- baseURL: process.env.OPENAI_BASE_URL,
37151
- ...getOpenAICommonOptions()
39109
+ const server = await createServer(servicePort);
39110
+ server.useMiddleware((req, res, next) => {
39111
+ console.log("Middleware triggered for request:", req.body.model);
39112
+ req.config = config;
39113
+ next();
37152
39114
  });
39115
+ server.useMiddleware(rewriteBody);
39116
+ if (config.Router?.background && config.Router?.think && config?.Router?.longContext) {
39117
+ server.useMiddleware(router);
39118
+ } else {
39119
+ server.useMiddleware((req, res, next) => {
39120
+ req.provider = "default";
39121
+ req.body.model = config.OPENAI_MODEL;
39122
+ next();
39123
+ });
39124
+ }
39125
+ server.useMiddleware(formatRequest);
37153
39126
  server.app.post("/v1/messages", async (req, res) => {
37154
39127
  try {
37155
- if (process.env.OPENAI_MODEL) {
37156
- req.body.model = process.env.OPENAI_MODEL;
37157
- }
37158
- const completion = await openai.chat.completions.create(req.body);
39128
+ const provider = getProviderInstance(req.provider || "default");
39129
+ const completion = await provider.chat.completions.create(req.body);
37159
39130
  await streamOpenAIResponse(res, completion, req.body.model, req.body);
37160
39131
  } catch (e2) {
37161
39132
  console.error("Error in OpenAI API call:", e2);
@@ -37165,29 +39136,6 @@ async function run(options = {}) {
37165
39136
  console.log(`\u{1F680} Claude Code Router is running on port ${servicePort}`);
37166
39137
  }
37167
39138
 
37168
- // src/utils/close.ts
37169
- var import_fs4 = require("fs");
37170
- var import_path2 = require("path");
37171
- async function closeService() {
37172
- const PID_FILE2 = (0, import_path2.join)(HOME_DIR, ".claude-code-router.pid");
37173
- if (!isServiceRunning()) {
37174
- console.log("No service is currently running.");
37175
- return;
37176
- }
37177
- if (getReferenceCount() > 0) {
37178
- return;
37179
- }
37180
- try {
37181
- const pid = parseInt((0, import_fs4.readFileSync)(PID_FILE2, "utf-8"));
37182
- process.kill(pid);
37183
- cleanupPidFile();
37184
- console.log("claude code router service has been successfully stopped.");
37185
- } catch (e2) {
37186
- console.log("Failed to stop the service. It may have already been stopped.");
37187
- cleanupPidFile();
37188
- }
37189
- }
37190
-
37191
39139
  // src/utils/status.ts
37192
39140
  function showStatus() {
37193
39141
  const info = getServiceInfo();
@@ -37214,23 +39162,51 @@ function showStatus() {
37214
39162
 
37215
39163
  // src/utils/codeCommand.ts
37216
39164
  var import_child_process = require("child_process");
39165
+
39166
+ // src/utils/close.ts
39167
+ var import_fs4 = require("fs");
39168
+ var import_path2 = require("path");
39169
+ async function closeService() {
39170
+ const PID_FILE2 = (0, import_path2.join)(HOME_DIR, ".claude-code-router.pid");
39171
+ if (!isServiceRunning()) {
39172
+ console.log("No service is currently running.");
39173
+ return;
39174
+ }
39175
+ if (getReferenceCount() > 0) {
39176
+ return;
39177
+ }
39178
+ try {
39179
+ const pid = parseInt((0, import_fs4.readFileSync)(PID_FILE2, "utf-8"));
39180
+ process.kill(pid);
39181
+ cleanupPidFile();
39182
+ console.log("claude code router service has been successfully stopped.");
39183
+ } catch (e2) {
39184
+ console.log("Failed to stop the service. It may have already been stopped.");
39185
+ cleanupPidFile();
39186
+ }
39187
+ }
39188
+
39189
+ // src/utils/codeCommand.ts
37217
39190
  async function executeCodeCommand(args = []) {
37218
39191
  const env = {
37219
39192
  ...process.env,
37220
39193
  DISABLE_PROMPT_CACHING: "1",
37221
39194
  ANTHROPIC_AUTH_TOKEN: "test",
37222
- ANTHROPIC_BASE_URL: "http://127.0.0.1:3456",
39195
+ ANTHROPIC_BASE_URL: `http://127.0.0.1:3456`,
37223
39196
  API_TIMEOUT_MS: "600000"
37224
39197
  };
37225
39198
  incrementReferenceCount();
37226
- const claudeProcess = (0, import_child_process.spawn)("claude", args, {
39199
+ const claudePath = process.env.CLAUDE_PATH || "claude";
39200
+ const claudeProcess = (0, import_child_process.spawn)(claudePath, args, {
37227
39201
  env,
37228
39202
  stdio: "inherit",
37229
39203
  shell: true
37230
39204
  });
37231
39205
  claudeProcess.on("error", (error) => {
37232
39206
  console.error("Failed to start claude command:", error.message);
37233
- console.log("Make sure Claude Code is installed: npm install -g @anthropic-ai/claude-code");
39207
+ console.log(
39208
+ "Make sure Claude Code is installed: npm install -g @anthropic-ai/claude-code"
39209
+ );
37234
39210
  decrementReferenceCount();
37235
39211
  process.exit(1);
37236
39212
  });
@@ -37242,10 +39218,11 @@ async function executeCodeCommand(args = []) {
37242
39218
  }
37243
39219
 
37244
39220
  // package.json
37245
- var version = "1.0.1";
39221
+ var version = "1.0.5";
37246
39222
 
37247
39223
  // src/cli.ts
37248
39224
  var import_child_process2 = require("child_process");
39225
+ var import_fs5 = require("fs");
37249
39226
  var command = process.argv[2];
37250
39227
  var HELP_TEXT = `
37251
39228
  Usage: claude-code [command]
@@ -37280,7 +39257,25 @@ async function main() {
37280
39257
  run();
37281
39258
  break;
37282
39259
  case "stop":
37283
- await closeService();
39260
+ try {
39261
+ const pid = parseInt((0, import_fs5.readFileSync)(PID_FILE, "utf-8"));
39262
+ process.kill(pid);
39263
+ cleanupPidFile();
39264
+ if ((0, import_fs5.existsSync)(REFERENCE_COUNT_FILE)) {
39265
+ try {
39266
+ require("fs").unlinkSync(REFERENCE_COUNT_FILE);
39267
+ } catch (e2) {
39268
+ }
39269
+ }
39270
+ console.log(
39271
+ "claude code router service has been successfully stopped."
39272
+ );
39273
+ } catch (e2) {
39274
+ console.log(
39275
+ "Failed to stop the service. It may have already been stopped."
39276
+ );
39277
+ cleanupPidFile();
39278
+ }
37284
39279
  break;
37285
39280
  case "status":
37286
39281
  showStatus();