@abtnode/core 1.16.54-beta-20251028-092308-569763e6 → 1.16.54-beta-20251029-230008-54c9843b

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.
@@ -2656,6 +2656,12 @@ class DiskBlockletManager extends BaseBlockletManager {
2656
2656
  options: { runOnInit: false },
2657
2657
  fn: () => this.cleanExpiredBlocklets(),
2658
2658
  },
2659
+ {
2660
+ name: 'send-serverless-heartbeat',
2661
+ time: process.env.ABT_NODE_SERVERLESS_HEARTBEAT_INTERVAL || '*/5 * * * *', // default every 5 minutes
2662
+ options: { runOnInit: false },
2663
+ fn: () => launcher.sendServerlessHeartbeat(),
2664
+ },
2659
2665
  ];
2660
2666
 
2661
2667
  logger.info('enable serverless jobs', serverlessJobs.map((x) => x.name).join(','));
@@ -31695,6 +31695,7 @@ const isSatisfiable = (comparators, options) => {
31695
31695
  // already replaced the hyphen ranges
31696
31696
  // turn into a set of JUST comparators.
31697
31697
  const parseComparator = (comp, options) => {
31698
+ comp = comp.replace(re[t.BUILD], '')
31698
31699
  debug('comp', comp, options)
31699
31700
  comp = replaceCarets(comp, options)
31700
31701
  debug('caret', comp)
@@ -32115,11 +32116,25 @@ class SemVer {
32115
32116
  other = new SemVer(other, this.options)
32116
32117
  }
32117
32118
 
32118
- return (
32119
- compareIdentifiers(this.major, other.major) ||
32120
- compareIdentifiers(this.minor, other.minor) ||
32121
- compareIdentifiers(this.patch, other.patch)
32122
- )
32119
+ if (this.major < other.major) {
32120
+ return -1
32121
+ }
32122
+ if (this.major > other.major) {
32123
+ return 1
32124
+ }
32125
+ if (this.minor < other.minor) {
32126
+ return -1
32127
+ }
32128
+ if (this.minor > other.minor) {
32129
+ return 1
32130
+ }
32131
+ if (this.patch < other.patch) {
32132
+ return -1
32133
+ }
32134
+ if (this.patch > other.patch) {
32135
+ return 1
32136
+ }
32137
+ return 0
32123
32138
  }
32124
32139
 
32125
32140
  comparePre (other) {
@@ -33020,6 +33035,10 @@ module.exports = debug
33020
33035
 
33021
33036
  const numeric = /^[0-9]+$/
33022
33037
  const compareIdentifiers = (a, b) => {
33038
+ if (typeof a === 'number' && typeof b === 'number') {
33039
+ return a === b ? 0 : a < b ? -1 : 1
33040
+ }
33041
+
33023
33042
  const anum = numeric.test(a)
33024
33043
  const bnum = numeric.test(b)
33025
33044
 
@@ -38964,7 +38983,7 @@ module.exports = require("zlib");
38964
38983
  /***/ ((module) => {
38965
38984
 
38966
38985
  "use strict";
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"}');
38986
+ 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.35","@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.53","@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"}');
38968
38987
 
38969
38988
  /***/ }),
38970
38989
 
@@ -7,6 +7,7 @@ const pick = require('lodash/pick');
7
7
  const uniq = require('lodash/uniq');
8
8
  const trim = require('lodash/trim');
9
9
  const merge = require('lodash/merge');
10
+ const si = require('systeminformation');
10
11
  const isEmpty = require('lodash/isEmpty');
11
12
  const {
12
13
  getUserAvatarUrl,
@@ -156,6 +157,85 @@ const notifyBlockletUpdated = (blocklet) => notifyLauncher('serverless.blocklet.
156
157
  const notifyBlockletStarted = (blocklet) => notifyLauncher('serverless.blocklet.started', blocklet);
157
158
  const notifyBlockletStopped = (blocklet) => notifyLauncher('serverless.blocklet.stopped', blocklet);
158
159
 
160
+ const getCpuUtilization = async () => {
161
+ const load = await si.currentLoad();
162
+ const u = Number(load?.currentLoad);
163
+
164
+ return Math.max(0, Math.min(1, u / 100));
165
+ };
166
+
167
+ const getComponentsAggregate = async () => {
168
+ try {
169
+ const list = await states.blocklet.getBlocklets();
170
+ const counts = {};
171
+ let total = 0;
172
+ list.forEach((b) => {
173
+ const children = Array.isArray(b.children) ? b.children : [];
174
+ children.forEach((child) => {
175
+ const key = fromBlockletStatus(child.status) || 'unknown';
176
+ counts[key] = (counts[key] || 0) + 1;
177
+ total += 1;
178
+ });
179
+ });
180
+
181
+ return { total, counts };
182
+ } catch (error) {
183
+ logger.error('getComponentsAggregate failed', { error });
184
+ return { total: 0, counts: {} };
185
+ }
186
+ };
187
+
188
+ const sendServerlessHeartbeat = async () => {
189
+ logger.info('send serverless heartbeat');
190
+ const nodeInfo = await states.node.read();
191
+ const launcherUrl = nodeInfo?.launcher?.url;
192
+ if (!launcherUrl) {
193
+ logger.error('skip heartbeat: launcher url not configured', {
194
+ launcher: nodeInfo?.launcher,
195
+ });
196
+ return null;
197
+ }
198
+
199
+ const { did } = nodeInfo;
200
+ const cpuCores = os.cpus().length;
201
+ const [mem, cpuUtilization, components] = await Promise.all([
202
+ si.mem(),
203
+ getCpuUtilization(),
204
+ getComponentsAggregate(),
205
+ ]);
206
+
207
+ const memoryAvailableMb = mem.available / 1024 / 1024;
208
+ const memoryTotalMb = mem.total / 1024 / 1024;
209
+
210
+ const payload = {
211
+ name: nodeInfo.name,
212
+ description: nodeInfo.description,
213
+ version,
214
+ did,
215
+ cpuUtilization,
216
+ memoryAvailableMb,
217
+ memoryTotalMb,
218
+ cpuCores,
219
+ components,
220
+ };
221
+
222
+ logger.debug('send serverless heartbeat payload', { did, launcherUrl, payload });
223
+
224
+ try {
225
+ const result = await doRequest(nodeInfo.sk, {
226
+ launcherUrl,
227
+ pathname: '/api/serverless/heartbeat',
228
+ payload,
229
+ method: 'post',
230
+ });
231
+ logger.info('sent heartbeat to launcher', { did, launcherUrl, result });
232
+ return result;
233
+ } catch (error) {
234
+ logger.error('send heartbeat failed', { error: error.message, did, launcherUrl });
235
+ return null;
236
+ }
237
+ };
238
+
159
239
  const consumeLauncherSession = async ({ params, blocklet }) => {
160
240
  try {
161
241
  const info = await states.node.read();
@@ -657,4 +737,5 @@ module.exports = {
657
737
  notifyBlockletStopped,
658
738
  launchBlockletByLauncher,
659
739
  launchBlockletWithoutWallet,
740
+ sendServerlessHeartbeat,
660
741
  };
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.16.54-beta-20251028-092308-569763e6",
6
+ "version": "1.16.54-beta-20251029-230008-54c9843b",
7
7
  "description": "",
8
8
  "main": "lib/index.js",
9
9
  "files": [
@@ -19,21 +19,21 @@
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-20251028-092308-569763e6",
23
- "@abtnode/auth": "1.16.54-beta-20251028-092308-569763e6",
24
- "@abtnode/certificate-manager": "1.16.54-beta-20251028-092308-569763e6",
25
- "@abtnode/constant": "1.16.54-beta-20251028-092308-569763e6",
26
- "@abtnode/cron": "1.16.54-beta-20251028-092308-569763e6",
27
- "@abtnode/db-cache": "1.16.54-beta-20251028-092308-569763e6",
28
- "@abtnode/docker-utils": "1.16.54-beta-20251028-092308-569763e6",
29
- "@abtnode/logger": "1.16.54-beta-20251028-092308-569763e6",
30
- "@abtnode/models": "1.16.54-beta-20251028-092308-569763e6",
31
- "@abtnode/queue": "1.16.54-beta-20251028-092308-569763e6",
32
- "@abtnode/rbac": "1.16.54-beta-20251028-092308-569763e6",
33
- "@abtnode/router-provider": "1.16.54-beta-20251028-092308-569763e6",
34
- "@abtnode/static-server": "1.16.54-beta-20251028-092308-569763e6",
35
- "@abtnode/timemachine": "1.16.54-beta-20251028-092308-569763e6",
36
- "@abtnode/util": "1.16.54-beta-20251028-092308-569763e6",
22
+ "@abtnode/analytics": "1.16.54-beta-20251029-230008-54c9843b",
23
+ "@abtnode/auth": "1.16.54-beta-20251029-230008-54c9843b",
24
+ "@abtnode/certificate-manager": "1.16.54-beta-20251029-230008-54c9843b",
25
+ "@abtnode/constant": "1.16.54-beta-20251029-230008-54c9843b",
26
+ "@abtnode/cron": "1.16.54-beta-20251029-230008-54c9843b",
27
+ "@abtnode/db-cache": "1.16.54-beta-20251029-230008-54c9843b",
28
+ "@abtnode/docker-utils": "1.16.54-beta-20251029-230008-54c9843b",
29
+ "@abtnode/logger": "1.16.54-beta-20251029-230008-54c9843b",
30
+ "@abtnode/models": "1.16.54-beta-20251029-230008-54c9843b",
31
+ "@abtnode/queue": "1.16.54-beta-20251029-230008-54c9843b",
32
+ "@abtnode/rbac": "1.16.54-beta-20251029-230008-54c9843b",
33
+ "@abtnode/router-provider": "1.16.54-beta-20251029-230008-54c9843b",
34
+ "@abtnode/static-server": "1.16.54-beta-20251029-230008-54c9843b",
35
+ "@abtnode/timemachine": "1.16.54-beta-20251029-230008-54c9843b",
36
+ "@abtnode/util": "1.16.54-beta-20251029-230008-54c9843b",
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,16 +45,16 @@
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-20251028-092308-569763e6",
49
- "@blocklet/did-space-js": "^1.1.34",
50
- "@blocklet/env": "1.16.54-beta-20251028-092308-569763e6",
48
+ "@blocklet/constant": "1.16.54-beta-20251029-230008-54c9843b",
49
+ "@blocklet/did-space-js": "^1.1.35",
50
+ "@blocklet/env": "1.16.54-beta-20251029-230008-54c9843b",
51
51
  "@blocklet/error": "^0.2.5",
52
- "@blocklet/meta": "1.16.54-beta-20251028-092308-569763e6",
53
- "@blocklet/resolver": "1.16.54-beta-20251028-092308-569763e6",
54
- "@blocklet/sdk": "1.16.54-beta-20251028-092308-569763e6",
55
- "@blocklet/server-js": "1.16.54-beta-20251028-092308-569763e6",
56
- "@blocklet/store": "1.16.54-beta-20251028-092308-569763e6",
57
- "@blocklet/theme": "^3.1.51",
52
+ "@blocklet/meta": "1.16.54-beta-20251029-230008-54c9843b",
53
+ "@blocklet/resolver": "1.16.54-beta-20251029-230008-54c9843b",
54
+ "@blocklet/sdk": "1.16.54-beta-20251029-230008-54c9843b",
55
+ "@blocklet/server-js": "1.16.54-beta-20251029-230008-54c9843b",
56
+ "@blocklet/store": "1.16.54-beta-20251029-230008-54c9843b",
57
+ "@blocklet/theme": "^3.1.53",
58
58
  "@fidm/x509": "^1.2.1",
59
59
  "@ocap/mcrypto": "^1.26.3",
60
60
  "@ocap/util": "^1.26.3",
@@ -118,5 +118,5 @@
118
118
  "express": "^4.18.2",
119
119
  "unzipper": "^0.10.11"
120
120
  },
121
- "gitHead": "6143a5fe06862e017da9a2dca2b0ff18c318587b"
121
+ "gitHead": "21cf7881f5759a9b82e1a852286f048af112bafa"
122
122
  }