@cloudbase/cloudbase-mcp 2.4.0-alpha.0 → 2.5.0

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.
Files changed (4) hide show
  1. package/dist/cli.cjs +426 -18
  2. package/dist/index.cjs +426 -18
  3. package/dist/index.js +7721 -7632
  4. package/package.json +2 -1
package/dist/cli.cjs CHANGED
@@ -100573,6 +100573,9 @@ async function createCloudBaseMcpServer(options) {
100573
100573
  if (logger) {
100574
100574
  server.logger = logger;
100575
100575
  }
100576
+ server.setLogger = (logger) => {
100577
+ server.logger = logger;
100578
+ };
100576
100579
  // Enable telemetry if requested
100577
100580
  if (enableTelemetry) {
100578
100581
  (0, tool_wrapper_js_1.wrapServerWithTelemetry)(server);
@@ -135174,7 +135177,7 @@ class TelemetryReporter {
135174
135177
  const nodeVersion = process.version; // Node.js版本
135175
135178
  const arch = os_1.default.arch(); // 系统架构
135176
135179
  // 从构建时注入的版本号获取MCP版本信息
135177
- const mcpVersion = process.env.npm_package_version || "2.4.0-alpha.0" || 0;
135180
+ const mcpVersion = process.env.npm_package_version || "2.5.0" || 0;
135178
135181
  return {
135179
135182
  userAgent: `${osType} ${osRelease} ${arch} ${nodeVersion} CloudBase-MCP/${mcpVersion}`,
135180
135183
  deviceId: this.deviceId,
@@ -185656,6 +185659,7 @@ exports.getClaudePrompt = getClaudePrompt;
185656
185659
  exports.registerRagTools = registerRagTools;
185657
185660
  const adm_zip_1 = __importDefault(__webpack_require__(30283));
185658
185661
  const fs = __importStar(__webpack_require__(79748));
185662
+ const lockfile_1 = __importDefault(__webpack_require__(80127));
185659
185663
  const os = __importStar(__webpack_require__(21820));
185660
185664
  const path = __importStar(__webpack_require__(39902));
185661
185665
  const zod_1 = __webpack_require__(21614);
@@ -185672,7 +185676,39 @@ const KnowledgeBaseIdMap = {
185672
185676
  // ============ 缓存配置 ============
185673
185677
  const CACHE_BASE_DIR = path.join(os.homedir(), ".cloudbase-mcp");
185674
185678
  const CACHE_META_FILE = path.join(CACHE_BASE_DIR, "cache-meta.json");
185679
+ const LOCK_FILE = path.join(CACHE_BASE_DIR, ".download.lock");
185675
185680
  const DEFAULT_CACHE_TTL_MS = 24 * 60 * 60 * 1000; // 默认 24 小时
185681
+ // Promise wrapper for lockfile methods
185682
+ function acquireLock(lockPath, options) {
185683
+ return new Promise((resolve, reject) => {
185684
+ if (options) {
185685
+ lockfile_1.default.lock(lockPath, options, (err) => {
185686
+ if (err)
185687
+ reject(err);
185688
+ else
185689
+ resolve();
185690
+ });
185691
+ }
185692
+ else {
185693
+ lockfile_1.default.lock(lockPath, (err) => {
185694
+ if (err)
185695
+ reject(err);
185696
+ else
185697
+ resolve();
185698
+ });
185699
+ }
185700
+ });
185701
+ }
185702
+ function releaseLock(lockPath) {
185703
+ return new Promise((resolve, reject) => {
185704
+ lockfile_1.default.unlock(lockPath, (err) => {
185705
+ if (err)
185706
+ reject(err);
185707
+ else
185708
+ resolve();
185709
+ });
185710
+ });
185711
+ }
185676
185712
  // 支持环境变量 CLOUDBASE_MCP_CACHE_TTL_MS 控制缓存过期时间(毫秒)
185677
185713
  const parsedCacheTTL = process.env.CLOUDBASE_MCP_CACHE_TTL_MS
185678
185714
  ? parseInt(process.env.CLOUDBASE_MCP_CACHE_TTL_MS, 10)
@@ -185842,14 +185878,19 @@ async function _doDownloadResources() {
185842
185878
  async function downloadResources() {
185843
185879
  const webTemplateDir = path.join(CACHE_BASE_DIR, "web-template");
185844
185880
  const openAPIDir = path.join(CACHE_BASE_DIR, "openapi");
185845
- // 检查缓存是否有效
185881
+ // 如果已有下载任务在进行中,共享该 Promise
185882
+ if (resourceDownloadPromise) {
185883
+ (0, logger_js_1.debug)("[downloadResources] 共享已有下载任务");
185884
+ return resourceDownloadPromise;
185885
+ }
185886
+ // 先快速检查缓存(不需要锁,因为只是读取)
185846
185887
  if (await canUseCache()) {
185847
185888
  try {
185848
185889
  // 检查两个目录都存在
185849
185890
  await Promise.all([fs.access(webTemplateDir), fs.access(openAPIDir)]);
185850
185891
  const files = await fs.readdir(openAPIDir);
185851
185892
  if (files.length > 0) {
185852
- (0, logger_js_1.debug)("[downloadResources] 使用缓存");
185893
+ (0, logger_js_1.debug)("[downloadResources] 使用缓存(快速路径)");
185853
185894
  return {
185854
185895
  webTemplateDir,
185855
185896
  openAPIDocs: OPENAPI_SOURCES.map((source) => ({
@@ -185864,21 +185905,61 @@ async function downloadResources() {
185864
185905
  // 缓存无效,需要重新下载
185865
185906
  }
185866
185907
  }
185867
- // 如果已有下载任务在进行中,共享该 Promise
185868
- if (resourceDownloadPromise) {
185869
- (0, logger_js_1.debug)("[downloadResources] 共享已有下载任务");
185870
- return resourceDownloadPromise;
185871
- }
185872
- // 创建新的下载任务
185908
+ // 创建新的下载任务,使用文件锁保护
185873
185909
  (0, logger_js_1.debug)("[downloadResources] 开始新下载任务");
185874
185910
  await fs.mkdir(CACHE_BASE_DIR, { recursive: true });
185875
- resourceDownloadPromise = _doDownloadResources()
185876
- .then(async (result) => {
185877
- await updateCache();
185878
- (0, logger_js_1.debug)("[downloadResources] 缓存已更新");
185879
- return result;
185880
- })
185881
- .finally(() => {
185911
+ resourceDownloadPromise = (async () => {
185912
+ // 尝试获取文件锁,最多等待 6 秒(30 次 × 200ms),每 200ms 轮询一次
185913
+ let lockAcquired = false;
185914
+ try {
185915
+ await acquireLock(LOCK_FILE, {
185916
+ wait: 30 * 200, // 总等待时间:6000ms (6 秒)
185917
+ pollPeriod: 200, // 轮询间隔:200ms
185918
+ stale: 5 * 60 * 1000, // 5 分钟,如果锁文件超过这个时间认为是过期的
185919
+ });
185920
+ lockAcquired = true;
185921
+ (0, logger_js_1.debug)("[downloadResources] 文件锁已获取");
185922
+ // 在持有锁的情况下再次检查缓存(可能其他进程已经下载完成)
185923
+ if (await canUseCache()) {
185924
+ try {
185925
+ // 检查两个目录都存在
185926
+ await Promise.all([fs.access(webTemplateDir), fs.access(openAPIDir)]);
185927
+ const files = await fs.readdir(openAPIDir);
185928
+ if (files.length > 0) {
185929
+ (0, logger_js_1.debug)("[downloadResources] 使用缓存(在锁保护下检查)");
185930
+ return {
185931
+ webTemplateDir,
185932
+ openAPIDocs: OPENAPI_SOURCES.map((source) => ({
185933
+ name: source.name,
185934
+ description: source.description,
185935
+ absolutePath: path.join(openAPIDir, `${source.name}.openapi.yaml`),
185936
+ })).filter((item) => files.includes(`${item.name}.openapi.yaml`)),
185937
+ };
185938
+ }
185939
+ }
185940
+ catch {
185941
+ // 缓存无效,需要重新下载
185942
+ }
185943
+ }
185944
+ // 执行下载
185945
+ const result = await _doDownloadResources();
185946
+ await updateCache();
185947
+ (0, logger_js_1.debug)("[downloadResources] 缓存已更新");
185948
+ return result;
185949
+ }
185950
+ finally {
185951
+ // 释放文件锁
185952
+ if (lockAcquired) {
185953
+ try {
185954
+ await releaseLock(LOCK_FILE);
185955
+ (0, logger_js_1.debug)("[downloadResources] 文件锁已释放");
185956
+ }
185957
+ catch (error) {
185958
+ (0, logger_js_1.warn)("[downloadResources] 释放文件锁失败", { error });
185959
+ }
185960
+ }
185961
+ }
185962
+ })().finally(() => {
185882
185963
  resourceDownloadPromise = null;
185883
185964
  });
185884
185965
  return resourceDownloadPromise;
@@ -201022,7 +201103,7 @@ ${envIdSection}
201022
201103
  ## 环境信息
201023
201104
  - 操作系统: ${os_1.default.type()} ${os_1.default.release()}
201024
201105
  - Node.js版本: ${process.version}
201025
- - MCP 版本:${process.env.npm_package_version || "2.4.0-alpha.0" || 0}
201106
+ - MCP 版本:${process.env.npm_package_version || "2.5.0" || 0}
201026
201107
  - 系统架构: ${os_1.default.arch()}
201027
201108
  - 时间: ${new Date().toISOString()}
201028
201109
  - 请求ID: ${requestId}
@@ -215691,7 +215772,7 @@ function registerSetupTools(server) {
215691
215772
  title: "下载项目模板",
215692
215773
  description: `自动下载并部署CloudBase项目模板。⚠️ **MANDATORY FOR NEW PROJECTS** ⚠️
215693
215774
 
215694
- **CRITICAL**: This tool MUST be called FIRST when starting a new project.\n\n支持的模板:\n- react: React + CloudBase 全栈应用模板\n- vue: Vue + CloudBase 全栈应用模板\n- miniprogram: 微信小程序 + 云开发模板 \n- uniapp: UniApp + CloudBase 跨端应用模板\n- rules: 只包含AI编辑器配置文件(包含Cursor、WindSurf、CodeBuddy等所有主流编辑器配置),适合在已有项目中补充AI编辑器配置\n\n支持的IDE类型:\n- all: 下载所有IDE配置(默认)\n- cursor: Cursor AI编辑器\n- windsurf: WindSurf AI编辑器\n- codebuddy: CodeBuddy AI编辑器\n- claude-code: Claude Code AI编辑器\n- cline: Cline AI编辑器\n- gemini-cli: Gemini CLI\n- opencode: OpenCode AI编辑器\n- qwen-code: 通义灵码\n- baidu-comate: 百度Comate\n- openai-codex-cli: OpenAI Codex CLI\n- augment-code: Augment Code\n- github-copilot: GitHub Copilot\n- roocode: RooCode AI编辑器\n- tongyi-lingma: 通义灵码\n- trae: Trae AI编辑器\n- qoder: Qoder AI编辑器\n- antigravity: Google Antigravity AI编辑器\n- vscode: Visual Studio Code\n\n特别说明:\n- rules 模板会自动包含当前 mcp 版本号信息(版本号:${ true ? "2.4.0-alpha.0" : 0}),便于后续维护和版本追踪\n- 下载 rules 模板时,如果项目中已存在 README.md 文件,系统会自动保护该文件不被覆盖(除非设置 overwrite=true)`,
215775
+ **CRITICAL**: This tool MUST be called FIRST when starting a new project.\n\n支持的模板:\n- react: React + CloudBase 全栈应用模板\n- vue: Vue + CloudBase 全栈应用模板\n- miniprogram: 微信小程序 + 云开发模板 \n- uniapp: UniApp + CloudBase 跨端应用模板\n- rules: 只包含AI编辑器配置文件(包含Cursor、WindSurf、CodeBuddy等所有主流编辑器配置),适合在已有项目中补充AI编辑器配置\n\n支持的IDE类型:\n- all: 下载所有IDE配置(默认)\n- cursor: Cursor AI编辑器\n- windsurf: WindSurf AI编辑器\n- codebuddy: CodeBuddy AI编辑器\n- claude-code: Claude Code AI编辑器\n- cline: Cline AI编辑器\n- gemini-cli: Gemini CLI\n- opencode: OpenCode AI编辑器\n- qwen-code: 通义灵码\n- baidu-comate: 百度Comate\n- openai-codex-cli: OpenAI Codex CLI\n- augment-code: Augment Code\n- github-copilot: GitHub Copilot\n- roocode: RooCode AI编辑器\n- tongyi-lingma: 通义灵码\n- trae: Trae AI编辑器\n- qoder: Qoder AI编辑器\n- antigravity: Google Antigravity AI编辑器\n- vscode: Visual Studio Code\n\n特别说明:\n- rules 模板会自动包含当前 mcp 版本号信息(版本号:${ true ? "2.5.0" : 0}),便于后续维护和版本追踪\n- 下载 rules 模板时,如果项目中已存在 README.md 文件,系统会自动保护该文件不被覆盖(除非设置 overwrite=true)`,
215695
215776
  inputSchema: {
215696
215777
  template: zod_1.z
215697
215778
  .enum(["react", "vue", "miniprogram", "uniapp", "rules"])
@@ -224736,6 +224817,333 @@ function resolveIds(schema) {
224736
224817
  }
224737
224818
 
224738
224819
 
224820
+ /***/ }),
224821
+
224822
+ /***/ 80127:
224823
+ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
224824
+
224825
+ var fs = __webpack_require__(29021)
224826
+
224827
+ var wx = 'wx'
224828
+ if (process.version.match(/^v0\.[0-6]/)) {
224829
+ var c = __webpack_require__(81115)
224830
+ wx = c.O_TRUNC | c.O_CREAT | c.O_WRONLY | c.O_EXCL
224831
+ }
224832
+
224833
+ var os = __webpack_require__(21820)
224834
+ exports.filetime = 'ctime'
224835
+ if (os.platform() == "win32") {
224836
+ exports.filetime = 'mtime'
224837
+ }
224838
+
224839
+ var debug
224840
+ var util = __webpack_require__(28354)
224841
+ if (util.debuglog)
224842
+ debug = util.debuglog('LOCKFILE')
224843
+ else if (/\blockfile\b/i.test(process.env.NODE_DEBUG))
224844
+ debug = function() {
224845
+ var msg = util.format.apply(util, arguments)
224846
+ console.error('LOCKFILE %d %s', process.pid, msg)
224847
+ }
224848
+ else
224849
+ debug = function() {}
224850
+
224851
+ var locks = {}
224852
+
224853
+ function hasOwnProperty (obj, prop) {
224854
+ return Object.prototype.hasOwnProperty.call(obj, prop)
224855
+ }
224856
+
224857
+ var onExit = __webpack_require__(29468)
224858
+ onExit(function () {
224859
+ debug('exit listener')
224860
+ // cleanup
224861
+ Object.keys(locks).forEach(exports.unlockSync)
224862
+ })
224863
+
224864
+ // XXX https://github.com/joyent/node/issues/3555
224865
+ // Remove when node 0.8 is deprecated.
224866
+ if (/^v0\.[0-8]\./.test(process.version)) {
224867
+ debug('uncaughtException, version = %s', process.version)
224868
+ process.on('uncaughtException', function H (er) {
224869
+ debug('uncaughtException')
224870
+ var l = process.listeners('uncaughtException').filter(function (h) {
224871
+ return h !== H
224872
+ })
224873
+ if (!l.length) {
224874
+ // cleanup
224875
+ try { Object.keys(locks).forEach(exports.unlockSync) } catch (e) {}
224876
+ process.removeListener('uncaughtException', H)
224877
+ throw er
224878
+ }
224879
+ })
224880
+ }
224881
+
224882
+ exports.unlock = function (path, cb) {
224883
+ debug('unlock', path)
224884
+ // best-effort. unlocking an already-unlocked lock is a noop
224885
+ delete locks[path]
224886
+ fs.unlink(path, function (unlinkEr) { cb && cb() })
224887
+ }
224888
+
224889
+ exports.unlockSync = function (path) {
224890
+ debug('unlockSync', path)
224891
+ // best-effort. unlocking an already-unlocked lock is a noop
224892
+ try { fs.unlinkSync(path) } catch (er) {}
224893
+ delete locks[path]
224894
+ }
224895
+
224896
+
224897
+ // if the file can be opened in readonly mode, then it's there.
224898
+ // if the error is something other than ENOENT, then it's not.
224899
+ exports.check = function (path, opts, cb) {
224900
+ if (typeof opts === 'function') cb = opts, opts = {}
224901
+ debug('check', path, opts)
224902
+ fs.open(path, 'r', function (er, fd) {
224903
+ if (er) {
224904
+ if (er.code !== 'ENOENT') return cb(er)
224905
+ return cb(null, false)
224906
+ }
224907
+
224908
+ if (!opts.stale) {
224909
+ return fs.close(fd, function (er) {
224910
+ return cb(er, true)
224911
+ })
224912
+ }
224913
+
224914
+ fs.fstat(fd, function (er, st) {
224915
+ if (er) return fs.close(fd, function (er2) {
224916
+ return cb(er)
224917
+ })
224918
+
224919
+ fs.close(fd, function (er) {
224920
+ var age = Date.now() - st[exports.filetime].getTime()
224921
+ return cb(er, age <= opts.stale)
224922
+ })
224923
+ })
224924
+ })
224925
+ }
224926
+
224927
+ exports.checkSync = function (path, opts) {
224928
+ opts = opts || {}
224929
+ debug('checkSync', path, opts)
224930
+ if (opts.wait) {
224931
+ throw new Error('opts.wait not supported sync for obvious reasons')
224932
+ }
224933
+
224934
+ try {
224935
+ var fd = fs.openSync(path, 'r')
224936
+ } catch (er) {
224937
+ if (er.code !== 'ENOENT') throw er
224938
+ return false
224939
+ }
224940
+
224941
+ if (!opts.stale) {
224942
+ try { fs.closeSync(fd) } catch (er) {}
224943
+ return true
224944
+ }
224945
+
224946
+ // file exists. however, might be stale
224947
+ if (opts.stale) {
224948
+ try {
224949
+ var st = fs.fstatSync(fd)
224950
+ } finally {
224951
+ fs.closeSync(fd)
224952
+ }
224953
+ var age = Date.now() - st[exports.filetime].getTime()
224954
+ return (age <= opts.stale)
224955
+ }
224956
+ }
224957
+
224958
+
224959
+
224960
+ var req = 1
224961
+ exports.lock = function (path, opts, cb) {
224962
+ if (typeof opts === 'function') cb = opts, opts = {}
224963
+ opts.req = opts.req || req++
224964
+ debug('lock', path, opts)
224965
+ opts.start = opts.start || Date.now()
224966
+
224967
+ if (typeof opts.retries === 'number' && opts.retries > 0) {
224968
+ debug('has retries', opts.retries)
224969
+ var retries = opts.retries
224970
+ opts.retries = 0
224971
+ cb = (function (orig) { return function cb (er, fd) {
224972
+ debug('retry-mutated callback')
224973
+ retries -= 1
224974
+ if (!er || retries < 0) return orig(er, fd)
224975
+
224976
+ debug('lock retry', path, opts)
224977
+
224978
+ if (opts.retryWait) setTimeout(retry, opts.retryWait)
224979
+ else retry()
224980
+
224981
+ function retry () {
224982
+ opts.start = Date.now()
224983
+ debug('retrying', opts.start)
224984
+ exports.lock(path, opts, cb)
224985
+ }
224986
+ }})(cb)
224987
+ }
224988
+
224989
+ // try to engage the lock.
224990
+ // if this succeeds, then we're in business.
224991
+ fs.open(path, wx, function (er, fd) {
224992
+ if (!er) {
224993
+ debug('locked', path, fd)
224994
+ locks[path] = fd
224995
+ return fs.close(fd, function () {
224996
+ return cb()
224997
+ })
224998
+ }
224999
+
225000
+ debug('failed to acquire lock', er)
225001
+
225002
+ // something other than "currently locked"
225003
+ // maybe eperm or something.
225004
+ if (er.code !== 'EEXIST') {
225005
+ debug('not EEXIST error', er)
225006
+ return cb(er)
225007
+ }
225008
+
225009
+ // someone's got this one. see if it's valid.
225010
+ if (!opts.stale) return notStale(er, path, opts, cb)
225011
+
225012
+ return maybeStale(er, path, opts, false, cb)
225013
+ })
225014
+ debug('lock return')
225015
+ }
225016
+
225017
+
225018
+ // Staleness checking algorithm
225019
+ // 1. acquire $lock, fail
225020
+ // 2. stat $lock, find that it is stale
225021
+ // 3. acquire $lock.STALE
225022
+ // 4. stat $lock, assert that it is still stale
225023
+ // 5. unlink $lock
225024
+ // 6. link $lock.STALE $lock
225025
+ // 7. unlink $lock.STALE
225026
+ // On any failure, clean up whatever we've done, and raise the error.
225027
+ function maybeStale (originalEr, path, opts, hasStaleLock, cb) {
225028
+ fs.stat(path, function (statEr, st) {
225029
+ if (statEr) {
225030
+ if (statEr.code === 'ENOENT') {
225031
+ // expired already!
225032
+ opts.stale = false
225033
+ debug('lock stale enoent retry', path, opts)
225034
+ exports.lock(path, opts, cb)
225035
+ return
225036
+ }
225037
+ return cb(statEr)
225038
+ }
225039
+
225040
+ var age = Date.now() - st[exports.filetime].getTime()
225041
+ if (age <= opts.stale) return notStale(originalEr, path, opts, cb)
225042
+
225043
+ debug('lock stale', path, opts)
225044
+ if (hasStaleLock) {
225045
+ exports.unlock(path, function (er) {
225046
+ if (er) return cb(er)
225047
+ debug('lock stale retry', path, opts)
225048
+ fs.link(path + '.STALE', path, function (er) {
225049
+ fs.unlink(path + '.STALE', function () {
225050
+ // best effort. if the unlink fails, oh well.
225051
+ cb(er)
225052
+ })
225053
+ })
225054
+ })
225055
+ } else {
225056
+ debug('acquire .STALE file lock', opts)
225057
+ exports.lock(path + '.STALE', opts, function (er) {
225058
+ if (er) return cb(er)
225059
+ maybeStale(originalEr, path, opts, true, cb)
225060
+ })
225061
+ }
225062
+ })
225063
+ }
225064
+
225065
+ function notStale (er, path, opts, cb) {
225066
+ debug('notStale', path, opts)
225067
+
225068
+ // if we can't wait, then just call it a failure
225069
+ if (typeof opts.wait !== 'number' || opts.wait <= 0) {
225070
+ debug('notStale, wait is not a number')
225071
+ return cb(er)
225072
+ }
225073
+
225074
+ // poll for some ms for the lock to clear
225075
+ var now = Date.now()
225076
+ var start = opts.start || now
225077
+ var end = start + opts.wait
225078
+
225079
+ if (end <= now)
225080
+ return cb(er)
225081
+
225082
+ debug('now=%d, wait until %d (delta=%d)', start, end, end-start)
225083
+ var wait = Math.min(end - start, opts.pollPeriod || 100)
225084
+ var timer = setTimeout(poll, wait)
225085
+
225086
+ function poll () {
225087
+ debug('notStale, polling', path, opts)
225088
+ exports.lock(path, opts, cb)
225089
+ }
225090
+ }
225091
+
225092
+ exports.lockSync = function (path, opts) {
225093
+ opts = opts || {}
225094
+ opts.req = opts.req || req++
225095
+ debug('lockSync', path, opts)
225096
+ if (opts.wait || opts.retryWait) {
225097
+ throw new Error('opts.wait not supported sync for obvious reasons')
225098
+ }
225099
+
225100
+ try {
225101
+ var fd = fs.openSync(path, wx)
225102
+ locks[path] = fd
225103
+ try { fs.closeSync(fd) } catch (er) {}
225104
+ debug('locked sync!', path, fd)
225105
+ return
225106
+ } catch (er) {
225107
+ if (er.code !== 'EEXIST') return retryThrow(path, opts, er)
225108
+
225109
+ if (opts.stale) {
225110
+ var st = fs.statSync(path)
225111
+ var ct = st[exports.filetime].getTime()
225112
+ if (!(ct % 1000) && (opts.stale % 1000)) {
225113
+ // probably don't have subsecond resolution.
225114
+ // round up the staleness indicator.
225115
+ // Yes, this will be wrong 1/1000 times on platforms
225116
+ // with subsecond stat precision, but that's acceptable
225117
+ // in exchange for not mistakenly removing locks on
225118
+ // most other systems.
225119
+ opts.stale = 1000 * Math.ceil(opts.stale / 1000)
225120
+ }
225121
+ var age = Date.now() - ct
225122
+ if (age > opts.stale) {
225123
+ debug('lockSync stale', path, opts, age)
225124
+ exports.unlockSync(path)
225125
+ return exports.lockSync(path, opts)
225126
+ }
225127
+ }
225128
+
225129
+ // failed to lock!
225130
+ debug('failed to lock', path, opts, er)
225131
+ return retryThrow(path, opts, er)
225132
+ }
225133
+ }
225134
+
225135
+ function retryThrow (path, opts, er) {
225136
+ if (typeof opts.retries === 'number' && opts.retries > 0) {
225137
+ var newRT = opts.retries - 1
225138
+ debug('retryThrow', path, opts, newRT)
225139
+ opts.retries = newRT
225140
+ return exports.lockSync(path, opts)
225141
+ }
225142
+ throw er
225143
+ }
225144
+
225145
+
225146
+
224739
225147
  /***/ }),
224740
225148
 
224741
225149
  /***/ 80280: