@abtnode/core 1.16.54-beta-20251024-030947-6f2889bf → 1.16.54-beta-20251028-073105-3ed10cef

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/lib/api/team.js CHANGED
@@ -947,25 +947,28 @@ class TeamAPI extends EventEmitter {
947
947
  }
948
948
  if (includeFederated) {
949
949
  const nodeInfo = await this.node.read();
950
- const blocklet = await getBlocklet({
951
- did: teamDid,
952
- states: this.states,
953
- dataDirs: this.dataDirs,
954
- useCache: true,
955
- });
956
- syncFederated({
957
- nodeInfo,
958
- blocklet,
959
- data: {
960
- users: [
961
- {
962
- action: user.approved ? 'unban' : 'ban',
963
- did: user.did,
964
- sourceAppPid: userDoc.sourceAppPid,
965
- },
966
- ],
967
- },
968
- });
950
+ // 只有 blocklet 需要执行这个操作
951
+ if (nodeInfo.did !== teamDid) {
952
+ const blocklet = await getBlocklet({
953
+ did: teamDid,
954
+ states: this.states,
955
+ dataDirs: this.dataDirs,
956
+ useCache: true,
957
+ });
958
+ syncFederated({
959
+ nodeInfo,
960
+ blocklet,
961
+ data: {
962
+ users: [
963
+ {
964
+ action: user.approved ? 'unban' : 'ban',
965
+ did: user.did,
966
+ sourceAppPid: userDoc.sourceAppPid,
967
+ },
968
+ ],
969
+ },
970
+ });
971
+ }
969
972
  }
970
973
  this.emit(TeamEvents.userUpdated, { teamDid, user: result });
971
974
  this.emit(TeamEvents.userPermissionUpdated, { teamDid, user: result });
@@ -16,8 +16,8 @@ class BlockletPm2Events extends EventEmitter {
16
16
 
17
17
  this.paused = true;
18
18
 
19
- const pm2Events = new Pm2Events();
20
- pm2Events
19
+ this.pm2Events = new Pm2Events();
20
+ this.pm2Events
21
21
  .on((name, details) => {
22
22
  if (this.paused) {
23
23
  return;
@@ -1200,6 +1200,7 @@ module.exports.getInstanceSize = () => instanceMap.size;
1200
1200
  module.exports.getAccessLogStream = getAccessLogStream;
1201
1201
  module.exports.deleteOldLogfiles = deleteOldLogfiles;
1202
1202
  module.exports.setupAccessLogger = setupAccessLogger;
1203
+ module.exports.instanceMap = instanceMap;
1203
1204
 
1204
1205
 
1205
1206
  /***/ }),
@@ -38963,7 +38964,7 @@ module.exports = require("zlib");
38963
38964
  /***/ ((module) => {
38964
38965
 
38965
38966
  "use strict";
38966
- module.exports = /*#__PURE__*/JSON.parse('{"name":"@abtnode/core","publishConfig":{"access":"public"},"version":"1.16.53","description":"","main":"lib/index.js","files":["lib"],"scripts":{"lint":"eslint tests lib --ignore-pattern \'tests/assets/*\'","lint:fix":"eslint --fix tests lib","test":"bun test","coverage":"bun test --coverage"},"keywords":[],"author":"wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)","license":"Apache-2.0","dependencies":{"@abtnode/analytics":"1.16.53","@abtnode/auth":"1.16.53","@abtnode/certificate-manager":"1.16.53","@abtnode/constant":"1.16.53","@abtnode/cron":"1.16.53","@abtnode/db-cache":"1.16.53","@abtnode/docker-utils":"1.16.53","@abtnode/logger":"1.16.53","@abtnode/models":"1.16.53","@abtnode/queue":"1.16.53","@abtnode/rbac":"1.16.53","@abtnode/router-provider":"1.16.53","@abtnode/static-server":"1.16.53","@abtnode/timemachine":"1.16.53","@abtnode/util":"1.16.53","@aigne/aigne-hub":"^0.10.3","@arcblock/did":"^1.26.3","@arcblock/did-connect-js":"^1.26.3","@arcblock/did-ext":"^1.26.3","@arcblock/did-motif":"^1.1.14","@arcblock/did-util":"^1.26.3","@arcblock/event-hub":"^1.26.3","@arcblock/jwt":"^1.26.3","@arcblock/pm2-events":"^0.0.5","@arcblock/validator":"^1.26.3","@arcblock/vc":"^1.26.3","@blocklet/constant":"1.16.53","@blocklet/did-space-js":"^1.1.34","@blocklet/env":"1.16.53","@blocklet/error":"^0.2.5","@blocklet/meta":"1.16.53","@blocklet/resolver":"1.16.53","@blocklet/sdk":"1.16.53","@blocklet/server-js":"1.16.53","@blocklet/store":"1.16.53","@blocklet/theme":"^3.1.51","@fidm/x509":"^1.2.1","@ocap/mcrypto":"^1.26.3","@ocap/util":"^1.26.3","@ocap/wallet":"^1.26.3","@slack/webhook":"^5.0.4","archiver":"^7.0.1","axios":"^1.7.9","axon":"^2.0.3","chalk":"^4.1.2","cross-spawn":"^7.0.3","dayjs":"^1.11.13","deep-diff":"^1.0.2","detect-port":"^1.5.1","envfile":"^7.1.0","escape-string-regexp":"^4.0.0","fast-glob":"^3.3.2","filesize":"^10.1.1","flat":"^5.0.2","fs-extra":"^11.2.0","get-port":"^5.1.1","hasha":"^5.2.2","is-base64":"^1.1.0","is-cidr":"4","is-ip":"3","is-url":"^1.2.4","joi":"17.12.2","joi-extension-semver":"^5.0.0","js-yaml":"^4.1.0","kill-port":"^2.0.1","lodash":"^4.17.21","node-stream-zip":"^1.15.0","p-all":"^3.0.0","p-limit":"^3.1.0","p-map":"^4.0.0","p-retry":"^4.6.2","p-wait-for":"^3.2.0","private-ip":"^2.3.4","rate-limiter-flexible":"^5.0.5","read-last-lines":"^1.8.0","semver":"^7.6.3","sequelize":"^6.35.0","shelljs":"^0.8.5","slugify":"^1.6.6","ssri":"^8.0.1","stream-throttle":"^0.1.3","stream-to-promise":"^3.0.0","systeminformation":"^5.23.3","tail":"^2.2.4","tar":"^6.1.11","transliteration":"^2.3.5","ua-parser-js":"^1.0.2","ufo":"^1.5.3","uuid":"^11.1.0","valid-url":"^1.0.9","which":"^2.0.2","xbytes":"^1.8.0"},"devDependencies":{"axios-mock-adapter":"^2.1.0","expand-tilde":"^2.0.2","express":"^4.18.2","jest":"^29.7.0","unzipper":"^0.10.11"},"gitHead":"e5764f753181ed6a7c615cd4fc6682aacf0cb7cd"}');
38967
+ module.exports = /*#__PURE__*/JSON.parse('{"name":"@abtnode/core","publishConfig":{"access":"public"},"version":"1.16.53","description":"","main":"lib/index.js","files":["lib"],"scripts":{"lint":"eslint tests lib --ignore-pattern \'tests/assets/*\'","lint:fix":"eslint --fix tests lib","test":"bun test --bail --timeout 30000","coverage":"bun test --bail --timeout 30000 --coverage"},"keywords":[],"author":"wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)","license":"Apache-2.0","dependencies":{"@abtnode/analytics":"1.16.53","@abtnode/auth":"1.16.53","@abtnode/certificate-manager":"1.16.53","@abtnode/constant":"1.16.53","@abtnode/cron":"1.16.53","@abtnode/db-cache":"1.16.53","@abtnode/docker-utils":"1.16.53","@abtnode/logger":"1.16.53","@abtnode/models":"1.16.53","@abtnode/queue":"1.16.53","@abtnode/rbac":"1.16.53","@abtnode/router-provider":"1.16.53","@abtnode/static-server":"1.16.53","@abtnode/timemachine":"1.16.53","@abtnode/util":"1.16.53","@aigne/aigne-hub":"^0.10.3","@arcblock/did":"^1.26.3","@arcblock/did-connect-js":"^1.26.3","@arcblock/did-ext":"^1.26.3","@arcblock/did-motif":"^1.1.14","@arcblock/did-util":"^1.26.3","@arcblock/event-hub":"^1.26.3","@arcblock/jwt":"^1.26.3","@arcblock/pm2-events":"^0.0.5","@arcblock/validator":"^1.26.3","@arcblock/vc":"^1.26.3","@blocklet/constant":"1.16.53","@blocklet/did-space-js":"^1.1.34","@blocklet/env":"1.16.53","@blocklet/error":"^0.2.5","@blocklet/meta":"1.16.53","@blocklet/resolver":"1.16.53","@blocklet/sdk":"1.16.53","@blocklet/server-js":"1.16.53","@blocklet/store":"1.16.53","@blocklet/theme":"^3.1.51","@fidm/x509":"^1.2.1","@ocap/mcrypto":"^1.26.3","@ocap/util":"^1.26.3","@ocap/wallet":"^1.26.3","@slack/webhook":"^5.0.4","archiver":"^7.0.1","axios":"^1.7.9","axon":"^2.0.3","chalk":"^4.1.2","cross-spawn":"^7.0.3","dayjs":"^1.11.13","deep-diff":"^1.0.2","detect-port":"^1.5.1","envfile":"^7.1.0","escape-string-regexp":"^4.0.0","fast-glob":"^3.3.2","filesize":"^10.1.1","flat":"^5.0.2","fs-extra":"^11.2.0","get-port":"^5.1.1","hasha":"^5.2.2","is-base64":"^1.1.0","is-cidr":"4","is-ip":"3","is-url":"^1.2.4","joi":"17.12.2","joi-extension-semver":"^5.0.0","js-yaml":"^4.1.0","kill-port":"^2.0.1","lodash":"^4.17.21","node-stream-zip":"^1.15.0","p-all":"^3.0.0","p-limit":"^3.1.0","p-map":"^4.0.0","p-retry":"^4.6.2","p-wait-for":"^3.2.0","private-ip":"^2.3.4","rate-limiter-flexible":"^5.0.5","read-last-lines":"^1.8.0","semver":"^7.6.3","sequelize":"^6.35.0","shelljs":"^0.8.5","slugify":"^1.6.6","ssri":"^8.0.1","stream-throttle":"^0.1.3","stream-to-promise":"^3.0.0","systeminformation":"^5.23.3","tail":"^2.2.4","tar":"^6.1.11","transliteration":"^2.3.5","ua-parser-js":"^1.0.2","ufo":"^1.5.3","uuid":"^11.1.0","valid-url":"^1.0.9","which":"^2.0.2","xbytes":"^1.8.0"},"devDependencies":{"axios-mock-adapter":"^2.1.0","expand-tilde":"^2.0.2","express":"^4.18.2","unzipper":"^0.10.11"},"gitHead":"e5764f753181ed6a7c615cd4fc6682aacf0cb7cd"}');
38967
38968
 
38968
38969
  /***/ }),
38969
38970
 
@@ -10,17 +10,17 @@ const logger = require('@abtnode/logger')('@abtnode/core:blocklet:security');
10
10
  const { _convertResponseHeaderPolicy, _formatResponseHeaderPolicy } = require('./utils');
11
11
  const { responseHeaderPolicySchema } = require('./validator');
12
12
 
13
- const getBlockletResponseHeaderPolicy = async ({ teamManager }, { did, id, formated = false }) => {
13
+ const getBlockletResponseHeaderPolicy = async ({ teamManager }, { did, id, formatted = false }) => {
14
14
  const { responseHeaderPolicyState } = await teamManager.getSecurityState(did);
15
15
  const result = await responseHeaderPolicyState.getResponseHeaderPolicy(id);
16
- return formated ? result : _convertResponseHeaderPolicy(result);
16
+ return formatted ? result : _convertResponseHeaderPolicy(result);
17
17
  };
18
- const getBlockletResponseHeaderPolicies = async ({ teamManager }, { did, formated = false }) => {
18
+ const getBlockletResponseHeaderPolicies = async ({ teamManager }, { did, formatted = false }) => {
19
19
  const { responseHeaderPolicyState } = await teamManager.getSecurityState(did);
20
20
  const result = await responseHeaderPolicyState.getResponseHeaderPolicies(undefined, undefined, {
21
21
  createdAt: -1,
22
22
  });
23
- const responseHeaderPolicies = result.map((item) => (formated ? item : _convertResponseHeaderPolicy(item)));
23
+ const responseHeaderPolicies = result.map((item) => (formatted ? item : _convertResponseHeaderPolicy(item)));
24
24
  return {
25
25
  responseHeaderPolicies,
26
26
  paging: null,
@@ -42,7 +42,7 @@ async function addBlockletResponseHeaderPolicy({ teamManager }, { did, data }) {
42
42
  return _convertResponseHeaderPolicy(result);
43
43
  }
44
44
  // HACK: 由于需要使用 this.emit,所以这里不能使用箭头函数(尝试过传入 emit,会报错,目前只能这样)
45
- async function updateBlockletResponseHeaderPolicy({ teamManager }, { did, data, formated = false }) {
45
+ async function updateBlockletResponseHeaderPolicy({ teamManager }, { did, data, formatted = false }) {
46
46
  const { responseHeaderPolicyState } = await teamManager.getSecurityState(did);
47
47
  const { value, error } = responseHeaderPolicySchema
48
48
  .concat(
@@ -60,7 +60,7 @@ async function updateBlockletResponseHeaderPolicy({ teamManager }, { did, data,
60
60
  }
61
61
  const result = await responseHeaderPolicyState.updateResponseHeaderPolicy(_formatResponseHeaderPolicy(value));
62
62
  this.emit(BlockletEvents.securityConfigUpdated, { did });
63
- return formated ? result : _convertResponseHeaderPolicy(result);
63
+ return formatted ? result : _convertResponseHeaderPolicy(result);
64
64
  }
65
65
  // HACK: 由于需要使用 this.emit,所以这里不能使用箭头函数(尝试过传入 emit,会报错,目前只能这样)
66
66
  async function deleteBlockletResponseHeaderPolicy({ teamManager }, { did, id }) {
@@ -17,7 +17,7 @@ const getBlockletSecurityRule = async ({ teamManager }, { did, id }) => {
17
17
  const result = await securityRuleState.getSecurityRule(id);
18
18
  return result;
19
19
  };
20
- const getBlockletSecurityRules = async ({ teamManager }, { did, includeDisabled = false, formated = false }) => {
20
+ const getBlockletSecurityRules = async ({ teamManager }, { did, includeDisabled = false, formatted = false }) => {
21
21
  const { securityRuleState, accessPolicyState, responseHeaderPolicyState } = await teamManager.getSecurityState(did);
22
22
  const include = [
23
23
  {
@@ -36,7 +36,7 @@ const getBlockletSecurityRules = async ({ teamManager }, { did, includeDisabled
36
36
  const result = await securityRuleState.model.findAll({ include, where });
37
37
  const securityRules = result.map((item) => {
38
38
  const resultItem = item.toJSON();
39
- if (resultItem.responseHeaderPolicy && !formated) {
39
+ if (resultItem.responseHeaderPolicy && !formatted) {
40
40
  resultItem.responseHeaderPolicy = _convertResponseHeaderPolicy(resultItem.responseHeaderPolicy);
41
41
  }
42
42
  return resultItem;
@@ -28,41 +28,6 @@ const getProcessInfo = (processId, { returnList } = {}) =>
28
28
  });
29
29
  });
30
30
 
31
- // type RuntimeInfo = {
32
- // pid: number;
33
- // uptime: number;
34
- // memoryUsage: number;
35
- // cpuUsage: number;
36
- // status: string;
37
- // };
38
-
39
- // type ServiceRuntimeInfo = RuntimeInfo & {
40
- // instanceCount: number;
41
- // };
42
-
43
- // type NodeHistoryItem = {
44
- // date: number;
45
- // cpu: number;
46
- // mem: number;
47
- // daemonMem: number;
48
- // serviceMem: number;
49
- // };
50
-
51
- // type History = Array<NodeHistoryItem>;
52
-
53
- // type Realtime = {
54
- // cpu: {};
55
- // mem: {};
56
- // os: {};
57
- // disks: [];
58
- // daemon: RuntimeInfo
59
- // service: ServiceRuntimeInfo
60
-
61
- // type MonitorData = {
62
- // realtime: Realtime;
63
- // history: History; // saved in sqlite database
64
- // }
65
-
66
31
  const DEFAULT_DATA = {
67
32
  realtime: {
68
33
  cpu: {},
@@ -368,16 +368,22 @@ const getAppSystemEnvironments = (blocklet, nodeInfo, dataDirs) => {
368
368
  const { wallet } = result;
369
369
  const appSk = toHex(wallet.secretKey);
370
370
  const appPk = toHex(wallet.publicKey);
371
+
372
+ const ethWallet = fromSecretKey(appSk.slice(0, 66), 'ethereum');
373
+ const ethPk = toHex(ethWallet.publicKey);
374
+
371
375
  const appId = wallet.address;
372
376
  const appName = title || name || result.name;
373
377
  const appDescription = description || result.description;
374
378
 
375
379
  const isMigrated = Array.isArray(blocklet.migratedFrom) && blocklet.migratedFrom.length > 0;
376
380
  const appPid = blocklet.appPid || appId;
377
- const appPsk = isMigrated ? blocklet.migratedFrom[0].appSk : appSk;
381
+ const appPsk = toHex(isMigrated ? blocklet.migratedFrom[0].appSk : appSk);
378
382
 
379
383
  // Calculate permanent public key (PPK)
380
384
  const appPpk = isMigrated ? toHex(fromSecretKey(appPsk, wallet.type).publicKey) : appPk;
385
+ const ethPermanentWallet = fromSecretKey(appPsk.slice(0, 66), 'ethereum');
386
+ const appPpkEth = toHex(ethPermanentWallet.publicKey);
381
387
 
382
388
  /* 获取 did domain 方式:
383
389
  * 1. 先从 site 里读
@@ -400,10 +406,12 @@ const getAppSystemEnvironments = (blocklet, nodeInfo, dataDirs) => {
400
406
  return {
401
407
  BLOCKLET_DID: did, // BLOCKLET_DID is always same as BLOCKLET_APP_PID in structV2 application
402
408
  BLOCKLET_APP_PK: appPk,
409
+ BLOCKLET_APP_PK_ETH: ethPk,
403
410
  BLOCKLET_APP_SK: appSk,
404
411
  BLOCKLET_APP_ID: appId,
405
412
  BLOCKLET_APP_PSK: appPsk, // permanent sk even the blocklet has been migrated
406
413
  BLOCKLET_APP_PPK: appPpk, // permanent pk corresponding to PSK
414
+ BLOCKLET_APP_PPK_ETH: appPpkEth, // permanent pk corresponding to PSK for ethereum
407
415
  BLOCKLET_APP_PID: appPid, // permanent did even the blocklet has been migrated
408
416
  BLOCKLET_APP_NAME: appName,
409
417
  BLOCKLET_APP_NAME_SLUG: urlPathFriendly(slugify(appName)),
@@ -530,7 +538,7 @@ const getRuntimeEnvironments = (blocklet, nodeEnvironments, ancestors, isGreen =
530
538
  // For Access Key authentication, components should use root app's wallet
531
539
  // This ensures consistent accessKeyId across parent and child components
532
540
  const accessKeyWallet = get(nodeEnvironments, 'ABT_NODE_SK')
533
- ? getBlockletWallet(root.meta.did, nodeEnvironments.ABT_NODE_SK, undefined, 1)
541
+ ? getBlockletWallet(root.appPid || root.meta.did, nodeEnvironments.ABT_NODE_SK, undefined, 1)
534
542
  : null;
535
543
 
536
544
  const BLOCKLET_APP_IDS = getBlockletAppIdList(root).join(',');
@@ -3,6 +3,7 @@ const canPackageReadWrite = require('@abtnode/util/lib/can-pkg-rw');
3
3
 
4
4
  const getDefaultAutoUpgrade = () => {
5
5
  try {
6
+ // eslint-disable-next-line no-use-before-define
6
7
  return canPackageReadWrite(process.env.ABT_NODE_BINARY_NAME, process.env.ABT_NODE_PACKAGE_NAME);
7
8
  } catch (err) {
8
9
  return false;
package/lib/util/log.js CHANGED
@@ -417,7 +417,11 @@ const createDownloadLogStream = async ({ node, did, days, now }) => {
417
417
  archive.rawPipe = archive.pipe.bind(archive);
418
418
  archive.pipe = (s) => {
419
419
  archive.rawPipe(s);
420
- archive.finalize();
420
+ // 延迟调用 finalize,确保 pipe 的内部流完全初始化
421
+ // 使用 setTimeout(0) 以避免在 Bun/Node 中 finalize 过早导致 zip 不完整
422
+ setTimeout(() => {
423
+ archive.finalize();
424
+ }, 0);
421
425
  };
422
426
 
423
427
  return archive;
@@ -1,46 +1,149 @@
1
1
  const maxBy = require('lodash/maxBy');
2
2
  const SysInfo = require('systeminformation');
3
3
 
4
- const getSysInfo = async () => {
5
- const info = await SysInfo.get({
6
- cpu: 'physicalCores',
7
- mem: '*',
8
- currentLoad: '*',
9
- fsSize: '*',
10
- diskLayout: '*',
11
- osInfo: 'platform',
12
- });
13
-
14
- let drives = info.fsSize;
15
- if (info.osInfo.platform === 'darwin') {
16
- const systemDrives = (info.fsSize || []).filter((x) => x.type === 'APFS');
17
- const rootDrive = systemDrives.find((x) => x.mount === '/');
18
- if (rootDrive) {
19
- const maxUsedDrive = maxBy(systemDrives, (x) => x.used);
20
- rootDrive.used = maxUsedDrive.used;
21
- drives = [rootDrive];
22
- } else {
23
- drives = [];
24
- }
25
- }
4
+ const TIMEOUT_MS = 3000; // 各模块超时 3 秒
5
+ const FS_CACHE_MS = 30_000; // fsSize 每 30 秒刷新一次
6
+ const OS_CACHE_MS = 120_000; // osInfo 每 120 秒刷新一次
26
7
 
27
- return {
28
- cpu: {
29
- ...info.currentLoad,
30
- ...info.cpu,
8
+ const SAFE_EMPTY = {
9
+ cpu: {
10
+ avgLoad: 0,
11
+ currentLoad: 0,
12
+ physicalCores: 0,
13
+ cores: 0,
14
+ currentLoadUser: 0,
15
+ currentLoadSystem: 0,
16
+ currentLoadIdle: 0,
17
+ },
18
+ mem: {
19
+ total: 0,
20
+ free: 0,
21
+ used: 0,
22
+ active: 0,
23
+ available: 0,
24
+ buffers: 0,
25
+ cached: 0,
26
+ },
27
+ os: {
28
+ platform: '',
29
+ distro: '',
30
+ release: '',
31
+ arch: '',
32
+ hostname: '',
33
+ },
34
+ disks: [
35
+ {
36
+ device: '',
37
+ mountPoint: '',
38
+ total: 0,
39
+ used: 0,
40
+ free: 0,
31
41
  },
32
- mem: info.mem,
33
- os: info.osInfo,
34
- disks: drives
35
- .map((x) => ({
36
- device: x.fs,
37
- mountPoint: x.mount,
38
- total: x.size,
39
- used: x.used,
40
- free: x.size - x.used,
41
- }))
42
- .filter((x) => x.total > 0 && x.mountPoint.startsWith('/')),
43
- };
42
+ ],
44
43
  };
45
44
 
45
+ // 缓存状态
46
+ let lastResult = SAFE_EMPTY;
47
+ let runningPromise = null;
48
+
49
+ // 模块级缓存
50
+ let fsSizeCache = null;
51
+ let fsSizeTime = 0;
52
+ let osInfoCache = null;
53
+ let osInfoTime = 0;
54
+
55
+ // 超时包装
56
+ function runWithTimeout(promise, ms) {
57
+ return Promise.race([
58
+ promise,
59
+ new Promise((_, reject) => setTimeout(() => reject(new Error('systeminformation timeout')), ms)),
60
+ ]);
61
+ }
62
+
63
+ async function getFsSizeSafe() {
64
+ const now = Date.now();
65
+ if (fsSizeCache && now - fsSizeTime < FS_CACHE_MS) return fsSizeCache;
66
+
67
+ try {
68
+ const res = await runWithTimeout(SysInfo.fsSize(), TIMEOUT_MS);
69
+ fsSizeCache = res;
70
+ fsSizeTime = now;
71
+ return res;
72
+ } catch (err) {
73
+ console.warn('[getSysInfo] fsSize error or timeout:', err.message);
74
+ return fsSizeCache || [];
75
+ }
76
+ }
77
+
78
+ async function getOsInfoSafe() {
79
+ const now = Date.now();
80
+ if (osInfoCache && now - osInfoTime < OS_CACHE_MS) return osInfoCache;
81
+
82
+ try {
83
+ const res = await runWithTimeout(SysInfo.osInfo(), TIMEOUT_MS);
84
+ osInfoCache = res;
85
+ osInfoTime = now;
86
+ return res;
87
+ } catch (err) {
88
+ console.warn('[getSysInfo] osInfo error or timeout:', err.message);
89
+ return osInfoCache || {};
90
+ }
91
+ }
92
+
93
+ function getSysInfo() {
94
+ if (runningPromise) return runningPromise.catch(() => lastResult);
95
+
96
+ runningPromise = (async () => {
97
+ try {
98
+ const [mem, currentLoad, fsSize, osInfo] = await Promise.all([
99
+ runWithTimeout(SysInfo.mem(), TIMEOUT_MS),
100
+ runWithTimeout(SysInfo.currentLoad(), TIMEOUT_MS),
101
+ getFsSizeSafe(),
102
+ getOsInfoSafe(),
103
+ ]);
104
+
105
+ let drives = fsSize;
106
+ if (osInfo.platform === 'darwin') {
107
+ const systemDrives = (fsSize || []).filter((x) => x.type === 'APFS');
108
+ const rootDrive = systemDrives.find((x) => x.mount === '/');
109
+ if (rootDrive) {
110
+ const maxUsedDrive = maxBy(systemDrives, (x) => x.used);
111
+ rootDrive.used = maxUsedDrive.used;
112
+ drives = [rootDrive];
113
+ } else {
114
+ drives = [];
115
+ }
116
+ }
117
+
118
+ const result = {
119
+ cpu: { ...SAFE_EMPTY.cpu, ...currentLoad },
120
+ mem: { ...SAFE_EMPTY.mem, ...mem },
121
+ os: { ...SAFE_EMPTY.os, ...osInfo },
122
+ disks:
123
+ drives && drives.length
124
+ ? drives
125
+ .map((x) => ({
126
+ device: x.fs || '',
127
+ mountPoint: x.mount || '',
128
+ total: x.size || 0,
129
+ used: x.used || 0,
130
+ free: x.size ? x.size - x.used : 0,
131
+ }))
132
+ .filter((x) => x.total >= 0)
133
+ : SAFE_EMPTY.disks,
134
+ };
135
+
136
+ lastResult = result;
137
+ return result;
138
+ } catch (err) {
139
+ console.warn('[getSysInfo] error or timeout:', err.message);
140
+ return lastResult;
141
+ } finally {
142
+ runningPromise = null;
143
+ }
144
+ })();
145
+
146
+ return runningPromise;
147
+ }
148
+
46
149
  module.exports.getSysInfo = getSysInfo;
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.16.54-beta-20251024-030947-6f2889bf",
6
+ "version": "1.16.54-beta-20251028-073105-3ed10cef",
7
7
  "description": "",
8
8
  "main": "lib/index.js",
9
9
  "files": [
@@ -12,28 +12,28 @@
12
12
  "scripts": {
13
13
  "lint": "eslint tests lib --ignore-pattern 'tests/assets/*'",
14
14
  "lint:fix": "eslint --fix tests lib",
15
- "test": "bun test",
16
- "coverage": "bun test --coverage"
15
+ "test": "bun test --bail --timeout 30000",
16
+ "coverage": "bun test --bail --timeout 30000 --coverage"
17
17
  },
18
18
  "keywords": [],
19
19
  "author": "wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)",
20
20
  "license": "Apache-2.0",
21
21
  "dependencies": {
22
- "@abtnode/analytics": "1.16.54-beta-20251024-030947-6f2889bf",
23
- "@abtnode/auth": "1.16.54-beta-20251024-030947-6f2889bf",
24
- "@abtnode/certificate-manager": "1.16.54-beta-20251024-030947-6f2889bf",
25
- "@abtnode/constant": "1.16.54-beta-20251024-030947-6f2889bf",
26
- "@abtnode/cron": "1.16.54-beta-20251024-030947-6f2889bf",
27
- "@abtnode/db-cache": "1.16.54-beta-20251024-030947-6f2889bf",
28
- "@abtnode/docker-utils": "1.16.54-beta-20251024-030947-6f2889bf",
29
- "@abtnode/logger": "1.16.54-beta-20251024-030947-6f2889bf",
30
- "@abtnode/models": "1.16.54-beta-20251024-030947-6f2889bf",
31
- "@abtnode/queue": "1.16.54-beta-20251024-030947-6f2889bf",
32
- "@abtnode/rbac": "1.16.54-beta-20251024-030947-6f2889bf",
33
- "@abtnode/router-provider": "1.16.54-beta-20251024-030947-6f2889bf",
34
- "@abtnode/static-server": "1.16.54-beta-20251024-030947-6f2889bf",
35
- "@abtnode/timemachine": "1.16.54-beta-20251024-030947-6f2889bf",
36
- "@abtnode/util": "1.16.54-beta-20251024-030947-6f2889bf",
22
+ "@abtnode/analytics": "1.16.54-beta-20251028-073105-3ed10cef",
23
+ "@abtnode/auth": "1.16.54-beta-20251028-073105-3ed10cef",
24
+ "@abtnode/certificate-manager": "1.16.54-beta-20251028-073105-3ed10cef",
25
+ "@abtnode/constant": "1.16.54-beta-20251028-073105-3ed10cef",
26
+ "@abtnode/cron": "1.16.54-beta-20251028-073105-3ed10cef",
27
+ "@abtnode/db-cache": "1.16.54-beta-20251028-073105-3ed10cef",
28
+ "@abtnode/docker-utils": "1.16.54-beta-20251028-073105-3ed10cef",
29
+ "@abtnode/logger": "1.16.54-beta-20251028-073105-3ed10cef",
30
+ "@abtnode/models": "1.16.54-beta-20251028-073105-3ed10cef",
31
+ "@abtnode/queue": "1.16.54-beta-20251028-073105-3ed10cef",
32
+ "@abtnode/rbac": "1.16.54-beta-20251028-073105-3ed10cef",
33
+ "@abtnode/router-provider": "1.16.54-beta-20251028-073105-3ed10cef",
34
+ "@abtnode/static-server": "1.16.54-beta-20251028-073105-3ed10cef",
35
+ "@abtnode/timemachine": "1.16.54-beta-20251028-073105-3ed10cef",
36
+ "@abtnode/util": "1.16.54-beta-20251028-073105-3ed10cef",
37
37
  "@aigne/aigne-hub": "^0.10.3",
38
38
  "@arcblock/did": "^1.26.3",
39
39
  "@arcblock/did-connect-js": "^1.26.3",
@@ -45,15 +45,15 @@
45
45
  "@arcblock/pm2-events": "^0.0.5",
46
46
  "@arcblock/validator": "^1.26.3",
47
47
  "@arcblock/vc": "^1.26.3",
48
- "@blocklet/constant": "1.16.54-beta-20251024-030947-6f2889bf",
48
+ "@blocklet/constant": "1.16.54-beta-20251028-073105-3ed10cef",
49
49
  "@blocklet/did-space-js": "^1.1.34",
50
- "@blocklet/env": "1.16.54-beta-20251024-030947-6f2889bf",
50
+ "@blocklet/env": "1.16.54-beta-20251028-073105-3ed10cef",
51
51
  "@blocklet/error": "^0.2.5",
52
- "@blocklet/meta": "1.16.54-beta-20251024-030947-6f2889bf",
53
- "@blocklet/resolver": "1.16.54-beta-20251024-030947-6f2889bf",
54
- "@blocklet/sdk": "1.16.54-beta-20251024-030947-6f2889bf",
55
- "@blocklet/server-js": "1.16.54-beta-20251024-030947-6f2889bf",
56
- "@blocklet/store": "1.16.54-beta-20251024-030947-6f2889bf",
52
+ "@blocklet/meta": "1.16.54-beta-20251028-073105-3ed10cef",
53
+ "@blocklet/resolver": "1.16.54-beta-20251028-073105-3ed10cef",
54
+ "@blocklet/sdk": "1.16.54-beta-20251028-073105-3ed10cef",
55
+ "@blocklet/server-js": "1.16.54-beta-20251028-073105-3ed10cef",
56
+ "@blocklet/store": "1.16.54-beta-20251028-073105-3ed10cef",
57
57
  "@blocklet/theme": "^3.1.51",
58
58
  "@fidm/x509": "^1.2.1",
59
59
  "@ocap/mcrypto": "^1.26.3",
@@ -116,8 +116,7 @@
116
116
  "axios-mock-adapter": "^2.1.0",
117
117
  "expand-tilde": "^2.0.2",
118
118
  "express": "^4.18.2",
119
- "jest": "^29.7.0",
120
119
  "unzipper": "^0.10.11"
121
120
  },
122
- "gitHead": "73e5a3a80b82a2a7c62d42fdc08207b28e67633e"
121
+ "gitHead": "3002dd309759dd23c921b098b9edbef08838b734"
123
122
  }