@abtnode/core 1.16.46-beta-20250709-123154-c05c363c → 1.16.47-beta-20250710-073736-01b9c1bc
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/blocklet/manager/disk.js +24 -35
- package/lib/blocklet/manager/engine.js +50 -38
- package/lib/blocklet/migration-dist/migration.cjs +1 -1
- package/lib/monitor/blocklet-runtime-monitor.js +0 -1
- package/lib/util/blocklet.js +11 -8
- package/lib/util/docker/debian-dockerfile.js +2 -2
- package/lib/util/docker/docker-install-dependenices.js +85 -0
- package/lib/util/docker/parse-docker-options-from-pm2.js +13 -39
- package/lib/util/ensure-bun.js +94 -0
- package/lib/util/install-external-dependencies.js +48 -26
- package/package.json +24 -24
|
@@ -908,21 +908,21 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
908
908
|
async (b, { env }) => {
|
|
909
909
|
const hookArgs = getHookArgs(b);
|
|
910
910
|
const needRunDocker = await checkNeedRunDocker(b.meta, env, nodeInfo, isExternalBlocklet(blocklet));
|
|
911
|
-
if (
|
|
912
|
-
if (hookName === 'postStart' && b.meta.scripts?.postStart) {
|
|
913
|
-
return dockerExec({
|
|
914
|
-
blocklet,
|
|
915
|
-
meta: b.meta,
|
|
916
|
-
script: b.meta.scripts?.postStart,
|
|
917
|
-
hookName,
|
|
918
|
-
nodeInfo,
|
|
919
|
-
env,
|
|
920
|
-
...hookArgs,
|
|
921
|
-
timeout: 20000,
|
|
922
|
-
});
|
|
923
|
-
}
|
|
911
|
+
if (!b.meta.scripts?.[hookName]) {
|
|
924
912
|
return null;
|
|
925
913
|
}
|
|
914
|
+
if (needRunDocker) {
|
|
915
|
+
return dockerExec({
|
|
916
|
+
blocklet,
|
|
917
|
+
meta: b.meta,
|
|
918
|
+
script: b.meta.scripts?.[hookName],
|
|
919
|
+
hookName,
|
|
920
|
+
nodeInfo,
|
|
921
|
+
env,
|
|
922
|
+
...hookArgs,
|
|
923
|
+
timeout: 20000,
|
|
924
|
+
});
|
|
925
|
+
}
|
|
926
926
|
return hooks[hookName](b, {
|
|
927
927
|
appDir: b.env.appDir,
|
|
928
928
|
hooks: Object.assign(b.meta.hooks || {}, b.meta.scripts || {}),
|
|
@@ -4225,14 +4225,7 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
4225
4225
|
blocklet,
|
|
4226
4226
|
meta: b.meta,
|
|
4227
4227
|
env: nextEnv,
|
|
4228
|
-
script: [
|
|
4229
|
-
b.meta.scripts?.preInstall,
|
|
4230
|
-
'export NODE_OPTIONS=--no-experimental-permission && pnpm config set store-dir /var/lib/blocklet/.pnpm-store --global && pnpm config set update-notifier false --global && pnpm install --shamefully-hoist --unsafe-perm --fetch-timeout=90000 --fetch-retries=5 || (echo "PNPM install Error, Retry with --force" && pnpm install --shamefully-hoist --unsafe-perm --fetch-timeout=90000 --fetch-retries=5 --force)',
|
|
4231
|
-
b.meta.scripts?.preFlight,
|
|
4232
|
-
'node docker-exec/run-script.cjs',
|
|
4233
|
-
]
|
|
4234
|
-
.filter(Boolean)
|
|
4235
|
-
.join(' && '),
|
|
4228
|
+
script: ['node docker-exec/run-script.cjs'].filter(Boolean).join(' && '),
|
|
4236
4229
|
hookName: 'migration',
|
|
4237
4230
|
nodeInfo,
|
|
4238
4231
|
runScriptDir: path.join(__dirname, '../migration-dist'),
|
|
@@ -4322,18 +4315,11 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
4322
4315
|
const env = getRuntimeEnvironments(blocklet, nodeEnvironments, {});
|
|
4323
4316
|
const needRunDocker = await checkNeedRunDocker(blocklet.meta, env, nodeInfo, isExternalBlocklet(blocklet));
|
|
4324
4317
|
|
|
4325
|
-
|
|
4326
|
-
// pre install
|
|
4327
|
-
await this._runUserHook('preInstall', blocklet, context);
|
|
4328
|
-
}
|
|
4329
|
-
|
|
4318
|
+
await this._runUserHook('preInstall', blocklet, context);
|
|
4330
4319
|
// post install
|
|
4331
4320
|
await this._runUserHook('postInstall', blocklet, context);
|
|
4332
4321
|
|
|
4333
|
-
|
|
4334
|
-
// pre flight
|
|
4335
|
-
await this._runUserHook('preFlight', blocklet, context);
|
|
4336
|
-
}
|
|
4322
|
+
await this._runUserHook('preFlight', blocklet, context);
|
|
4337
4323
|
|
|
4338
4324
|
await this._runMigration({ needRunDocker, did, blocklet, oldBlocklet, componentDids });
|
|
4339
4325
|
|
|
@@ -4705,6 +4691,14 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
4705
4691
|
const env = getRuntimeEnvironments(b, nodeEnvironments, ancestors);
|
|
4706
4692
|
const needRunDocker = await checkNeedRunDocker(b.meta, env, nodeInfo, isExternalBlocklet(blocklet));
|
|
4707
4693
|
const hookArgs = getHookArgs(b);
|
|
4694
|
+
|
|
4695
|
+
if (name === 'preInstall') {
|
|
4696
|
+
await installExternalDependencies({
|
|
4697
|
+
appDir: b.env.appDir,
|
|
4698
|
+
nodeInfo,
|
|
4699
|
+
});
|
|
4700
|
+
}
|
|
4701
|
+
|
|
4708
4702
|
if (needRunDocker) {
|
|
4709
4703
|
const script = b.meta.scripts?.[name];
|
|
4710
4704
|
if (script && afterRunScripts.has(name)) {
|
|
@@ -4720,11 +4714,6 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
4720
4714
|
}
|
|
4721
4715
|
return null;
|
|
4722
4716
|
}
|
|
4723
|
-
if (name === 'preInstall') {
|
|
4724
|
-
await installExternalDependencies({
|
|
4725
|
-
appDir: b.env.appDir,
|
|
4726
|
-
});
|
|
4727
|
-
}
|
|
4728
4717
|
|
|
4729
4718
|
return hooks[name](b.meta.title, {
|
|
4730
4719
|
hooks: Object.assign(b.meta.hooks || {}, b.meta.scripts || {}),
|
|
@@ -2,6 +2,7 @@ const shelljs = require('shelljs');
|
|
|
2
2
|
const semver = require('semver');
|
|
3
3
|
const { ABT_NODE_KERNEL_OR_BLOCKLET_MODE } = require('@blocklet/constant');
|
|
4
4
|
const logger = require('@abtnode/logger')('@abtnode/core:blocklet:engine');
|
|
5
|
+
const { BUN_VERSION } = require('../../util/ensure-bun');
|
|
5
6
|
|
|
6
7
|
// eslint-disable-next-line no-underscore-dangle
|
|
7
8
|
const _getVersion = (fn, name) => {
|
|
@@ -41,44 +42,55 @@ function describe() {
|
|
|
41
42
|
};
|
|
42
43
|
}
|
|
43
44
|
|
|
44
|
-
const engineMap = new Map(
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
45
|
+
const engineMap = new Map();
|
|
46
|
+
|
|
47
|
+
engineMap.set('node', {
|
|
48
|
+
name: 'node',
|
|
49
|
+
displayName: 'Node.js',
|
|
50
|
+
interpreter: 'node',
|
|
51
|
+
description: 'Powered by Node.js',
|
|
52
|
+
args:
|
|
53
|
+
process.env.ABT_NODE_KERNEL_MODE === ABT_NODE_KERNEL_OR_BLOCKLET_MODE.PERFORMANT
|
|
54
|
+
? '--max-http-header-size=16384'
|
|
55
|
+
: '--max-http-header-size=16384 --optimize_for_size',
|
|
56
|
+
visible: true,
|
|
57
|
+
version() {
|
|
58
|
+
return _getVersion(() => process.version, this.name);
|
|
59
|
+
},
|
|
60
|
+
describe,
|
|
61
|
+
isAvailable() {
|
|
62
|
+
return _isAvailable(this.name);
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
engineMap.set('bun', {
|
|
67
|
+
name: 'bun',
|
|
68
|
+
displayName: 'Bun',
|
|
69
|
+
interpreter: 'bun',
|
|
70
|
+
description: 'Powered by Bun',
|
|
71
|
+
args: '',
|
|
72
|
+
visible: true,
|
|
73
|
+
version() {
|
|
74
|
+
return BUN_VERSION;
|
|
75
|
+
},
|
|
76
|
+
describe,
|
|
77
|
+
isAvailable() {
|
|
78
|
+
return _isAvailable(this.name);
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
engineMap.set('binary', {
|
|
83
|
+
name: 'binary',
|
|
84
|
+
visible: false,
|
|
85
|
+
displayName: 'Executable binary',
|
|
86
|
+
interpreter: 'none',
|
|
87
|
+
description: 'Executable binary',
|
|
88
|
+
version() {
|
|
89
|
+
return '';
|
|
90
|
+
},
|
|
91
|
+
describe,
|
|
92
|
+
isAvailable: () => true,
|
|
93
|
+
});
|
|
82
94
|
|
|
83
95
|
const engineNames = [...engineMap.keys()];
|
|
84
96
|
|
|
@@ -38902,7 +38902,7 @@ module.exports = require("zlib");
|
|
|
38902
38902
|
/***/ ((module) => {
|
|
38903
38903
|
|
|
38904
38904
|
"use strict";
|
|
38905
|
-
module.exports = /*#__PURE__*/JSON.parse('{"name":"@abtnode/core","publishConfig":{"access":"public"},"version":"1.16.
|
|
38905
|
+
module.exports = /*#__PURE__*/JSON.parse('{"name":"@abtnode/core","publishConfig":{"access":"public"},"version":"1.16.46","description":"","main":"lib/index.js","files":["lib"],"scripts":{"lint":"eslint tests lib --ignore-pattern \'tests/assets/*\'","lint:fix":"eslint --fix tests lib","test":"node tools/jest.js","coverage":"npm run test -- --coverage"},"keywords":[],"author":"wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)","license":"Apache-2.0","dependencies":{"@abtnode/analytics":"1.16.46","@abtnode/auth":"1.16.46","@abtnode/certificate-manager":"1.16.46","@abtnode/client":"1.16.46","@abtnode/constant":"1.16.46","@abtnode/cron":"1.16.46","@abtnode/db-cache":"1.16.46","@abtnode/docker-utils":"1.16.46","@abtnode/logger":"1.16.46","@abtnode/models":"1.16.46","@abtnode/queue":"1.16.46","@abtnode/rbac":"1.16.46","@abtnode/router-provider":"1.16.46","@abtnode/static-server":"1.16.46","@abtnode/timemachine":"1.16.46","@abtnode/util":"1.16.46","@arcblock/did":"1.20.15","@arcblock/did-auth":"1.20.15","@arcblock/did-ext":"1.20.15","@arcblock/did-motif":"^1.1.14","@arcblock/did-util":"1.20.15","@arcblock/event-hub":"1.20.15","@arcblock/jwt":"1.20.15","@arcblock/pm2-events":"^0.0.5","@arcblock/validator":"1.20.15","@arcblock/vc":"1.20.15","@blocklet/constant":"1.16.46","@blocklet/did-space-js":"^1.1.5","@blocklet/env":"1.16.46","@blocklet/error":"^0.2.5","@blocklet/meta":"1.16.46","@blocklet/resolver":"1.16.46","@blocklet/sdk":"1.16.46","@blocklet/store":"1.16.46","@blocklet/theme":"^3.0.23","@fidm/x509":"^1.2.1","@ocap/mcrypto":"1.20.15","@ocap/util":"1.20.15","@ocap/wallet":"1.20.15","@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","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":"^9.0.1","valid-url":"^1.0.9","which":"^2.0.2","xbytes":"^1.8.0"},"devDependencies":{"expand-tilde":"^2.0.2","express":"^4.18.2","jest":"^29.7.0","unzipper":"^0.10.11"},"gitHead":"e5764f753181ed6a7c615cd4fc6682aacf0cb7cd"}');
|
|
38906
38906
|
|
|
38907
38907
|
/***/ }),
|
|
38908
38908
|
|
|
@@ -152,7 +152,6 @@ class BlockletRuntimeMonitor extends EventEmitter {
|
|
|
152
152
|
appMem += runtimeInfo.memoryUsage || 0;
|
|
153
153
|
runningDocker = runningDocker || runtimeInfo.runningDocker;
|
|
154
154
|
} catch (err) {
|
|
155
|
-
console.error(err);
|
|
156
155
|
// component status in db may not sync with pm2 when server has just started
|
|
157
156
|
if (err.code !== 'BLOCKLET_PROCESS_404') {
|
|
158
157
|
this.logger.error('failed to get blocklet runtime info', { processId, error: err });
|
package/lib/util/blocklet.js
CHANGED
|
@@ -128,10 +128,10 @@ const {
|
|
|
128
128
|
const { installExternalDependencies } = require('./install-external-dependencies');
|
|
129
129
|
const parseDockerOptionsFromPm2 = require('./docker/parse-docker-options-from-pm2');
|
|
130
130
|
const dockerRemoveByName = require('./docker/docker-remove-by-name');
|
|
131
|
-
const checkNeedRunDocker = require('./docker/check-need-run-docker');
|
|
132
131
|
const getDockerRuntimeInfo = require('./docker/get-docker-runtime-info');
|
|
133
132
|
const parseDockerName = require('./docker/parse-docker-name');
|
|
134
133
|
const { createDockerNetwork } = require('./docker/docker-network');
|
|
134
|
+
const { ensureBun } = require('./ensure-bun');
|
|
135
135
|
|
|
136
136
|
/**
|
|
137
137
|
* get blocklet engine info, default is node
|
|
@@ -656,14 +656,10 @@ const startBlockletProcess = async (
|
|
|
656
656
|
// get env
|
|
657
657
|
const env = getRuntimeEnvironments(b, nodeEnvironments, ancestors);
|
|
658
658
|
const startedAt = Date.now();
|
|
659
|
-
const needRunDocker = await checkNeedRunDocker(b.meta, env, nodeInfo, isExternalBlocklet(blocklet));
|
|
660
659
|
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
await preFlight(b, { env: { ...env } });
|
|
665
|
-
await preStart(b, { env: { ...env } });
|
|
666
|
-
}
|
|
660
|
+
await installExternalDependencies({ appDir: env?.BLOCKLET_APP_DIR, nodeInfo });
|
|
661
|
+
await preFlight(b, { env: { ...env } });
|
|
662
|
+
await preStart(b, { env: { ...env } });
|
|
667
663
|
|
|
668
664
|
// kill process if port is occupied
|
|
669
665
|
try {
|
|
@@ -748,6 +744,13 @@ const startBlockletProcess = async (
|
|
|
748
744
|
serverSk: nodeEnvironments.ABT_NODE_SK,
|
|
749
745
|
});
|
|
750
746
|
|
|
747
|
+
if (options.interpreter === 'bun') {
|
|
748
|
+
options.exec_interpreter = await ensureBun();
|
|
749
|
+
options.exec_mode = 'fork';
|
|
750
|
+
delete options.instances;
|
|
751
|
+
delete options.mergeLogs;
|
|
752
|
+
}
|
|
753
|
+
|
|
751
754
|
const nextOptions =
|
|
752
755
|
b.mode === BLOCKLET_MODES.DEVELOPMENT
|
|
753
756
|
? options
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
const debianWrapDockerfile = require('./debian-wrap-dockerfile');
|
|
2
2
|
|
|
3
3
|
// Define Dockerfile with dynamic UID/GID mapping
|
|
4
|
-
const dockerfile = debianWrapDockerfile('arcblock/blocklet-base:0.0.
|
|
4
|
+
const dockerfile = debianWrapDockerfile('arcblock/blocklet-base:0.0.2');
|
|
5
5
|
|
|
6
6
|
module.exports = {
|
|
7
7
|
dockerfile,
|
|
8
|
-
image: '
|
|
8
|
+
image: 'debian_node_v4',
|
|
9
9
|
shell: 'sh',
|
|
10
10
|
network: '--network host',
|
|
11
11
|
baseDir: '/var/lib/blocklet',
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const fs = require('fs/promises');
|
|
3
|
+
const os = require('os');
|
|
4
|
+
const { DBCache, getAbtNodeRedisAndSQLiteUrl } = require('@abtnode/db-cache');
|
|
5
|
+
const promiseSpawn = require('@abtnode/util/lib/promise-spawn');
|
|
6
|
+
const logger = require('@abtnode/logger')('@abtnode/docker-exec-chown');
|
|
7
|
+
const parseDockerName = require('./parse-docker-name');
|
|
8
|
+
const { checkDockerHasImage } = require('./check-docker-has-image');
|
|
9
|
+
const { createDockerImage } = require('./create-docker-image');
|
|
10
|
+
const debianDockerfile = require('./debian-dockerfile');
|
|
11
|
+
const { getBunCacheDir } = require('../ensure-bun');
|
|
12
|
+
|
|
13
|
+
const lockFile = new DBCache(() => ({
|
|
14
|
+
prefix: 'docker-exec-chown-locks',
|
|
15
|
+
ttl: 1000 * 60 * 2,
|
|
16
|
+
...getAbtNodeRedisAndSQLiteUrl(),
|
|
17
|
+
}));
|
|
18
|
+
|
|
19
|
+
const LAST_INSTALL_NODE_MODULES_OS = 'node_modules_os_lock';
|
|
20
|
+
|
|
21
|
+
const saveLastInstallOs = async (installDir, isDocker = false) => {
|
|
22
|
+
const lastInstallOsLockPath = path.join(installDir, LAST_INSTALL_NODE_MODULES_OS);
|
|
23
|
+
await fs.writeFile(lastInstallOsLockPath, isDocker ? 'Linux' : os.type());
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const loadLastInstallOs = async (installDir) => {
|
|
27
|
+
const lastInstallOsLockPath = path.join(installDir, LAST_INSTALL_NODE_MODULES_OS);
|
|
28
|
+
try {
|
|
29
|
+
await fs.access(lastInstallOsLockPath);
|
|
30
|
+
const lastInstallOs = await fs.readFile(lastInstallOsLockPath, 'utf-8');
|
|
31
|
+
return lastInstallOs.trim();
|
|
32
|
+
} catch (_) {
|
|
33
|
+
return '';
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const isSameOs = async (installDir, isDocker = false) => {
|
|
38
|
+
const lastInstallOs = await loadLastInstallOs(installDir);
|
|
39
|
+
if (!lastInstallOs) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
return lastInstallOs === (isDocker ? 'Linux' : os.type());
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
async function dockerInstallDependencies({ name, installDir }) {
|
|
46
|
+
const { image, baseDir } = debianDockerfile;
|
|
47
|
+
|
|
48
|
+
if (!(await checkDockerHasImage(image))) {
|
|
49
|
+
await createDockerImage({
|
|
50
|
+
appDir: path.join(process.env.ABT_NODE_DATA_DIR, 'tmp', 'docker'),
|
|
51
|
+
dataDir: path.join(process.env.ABT_NODE_DATA_DIR, 'tmp', 'docker'),
|
|
52
|
+
meta: {},
|
|
53
|
+
ports: [],
|
|
54
|
+
env: {},
|
|
55
|
+
doChown: true,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const bunCacheDir = await getBunCacheDir(true);
|
|
60
|
+
|
|
61
|
+
const needChangeDir = [
|
|
62
|
+
{ source: installDir, target: `${baseDir}/blocklet` },
|
|
63
|
+
{ source: bunCacheDir, target: `${baseDir}/bun-cache` },
|
|
64
|
+
];
|
|
65
|
+
|
|
66
|
+
const volumes = needChangeDir.map((dir) => `-v ${dir.source}:${dir.target}:rw`).join(' ');
|
|
67
|
+
|
|
68
|
+
const realName = parseDockerName(name, 'docker-install-dependencies');
|
|
69
|
+
const startTime = Date.now();
|
|
70
|
+
|
|
71
|
+
await lockFile.acquire(realName);
|
|
72
|
+
try {
|
|
73
|
+
await promiseSpawn(
|
|
74
|
+
`docker rm -fv ${realName} > /dev/null 2>&1 || true && docker run --rm --name ${realName} ${volumes} --env BUN_INSTALL_CACHE_DIR=${needChangeDir[1].target} ${image} sh -c 'cd ${needChangeDir[0].target} && bun install'`,
|
|
75
|
+
{},
|
|
76
|
+
{ timeout: 1000 * 120, retry: 3 }
|
|
77
|
+
);
|
|
78
|
+
} finally {
|
|
79
|
+
await lockFile.releaseLock(realName);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
logger.info(`docker-install-dependencies ${name} cost time: ${Date.now() - startTime}ms`);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
module.exports = { dockerInstallDependencies, isSameOs, saveLastInstallOs, loadLastInstallOs };
|
|
@@ -12,8 +12,9 @@ const { NODE_MODES } = require('@abtnode/constant');
|
|
|
12
12
|
const promiseSpawn = require('@abtnode/util/lib/promise-spawn');
|
|
13
13
|
const getLocalIPAddress = require('@abtnode/util/lib/get-local-ip-address');
|
|
14
14
|
const { dockerCmdValidator } = require('@abtnode/docker-utils');
|
|
15
|
-
|
|
15
|
+
const { getBlockletEngine } = require('@blocklet/meta/lib/engine');
|
|
16
16
|
const { isExternalBlocklet } = require('@blocklet/meta/lib/util');
|
|
17
|
+
|
|
17
18
|
const parseDockerName = require('./parse-docker-name');
|
|
18
19
|
const { createDockerImage } = require('./create-docker-image');
|
|
19
20
|
const checkNeedRunDocker = require('./check-need-run-docker');
|
|
@@ -122,6 +123,7 @@ async function parseDockerOptionsFromPm2({
|
|
|
122
123
|
NODE_MODES: options.env.NODE_MODES || (isServerless ? NODE_MODES.SERVERLESS : NODE_MODES.PRODUCTION),
|
|
123
124
|
HTTP_PROXY: process.env.DOCKER_HTTP_PROXY || '',
|
|
124
125
|
HTTPS_PROXY: process.env.DOCKER_HTTPS_PROXY || '',
|
|
126
|
+
BUN_INSTALL_CACHE_DIR: '/var/lib/blocklet/bun-cache',
|
|
125
127
|
};
|
|
126
128
|
|
|
127
129
|
nextOptions.env = { ...nextOptions.env, ...envDefaults };
|
|
@@ -185,21 +187,6 @@ async function parseDockerOptionsFromPm2({
|
|
|
185
187
|
|
|
186
188
|
replaceEnvValue(dockerEnv, rootBlocklet, dockerNamePrefix);
|
|
187
189
|
|
|
188
|
-
let nodeModulesName = 'node_modules';
|
|
189
|
-
let installScript = '';
|
|
190
|
-
const appDir = nextOptions.env.BLOCKLET_APP_DIR;
|
|
191
|
-
const packageJsonPath = path.join(appDir, 'package.json');
|
|
192
|
-
const compactJsPath = path.join(appDir, 'blocklet-compact.js');
|
|
193
|
-
|
|
194
|
-
if (dockerInfo.installNodeModules && existsSync(packageJsonPath) && existsSync(compactJsPath)) {
|
|
195
|
-
const packageJson = JSON.parse(await fsp.readFile(packageJsonPath, 'utf-8'));
|
|
196
|
-
if (packageJson.dependencies || packageJson.devDependencies) {
|
|
197
|
-
nodeModulesName = 'docker_node_modules_v4';
|
|
198
|
-
|
|
199
|
-
installScript = `export NODE_OPTIONS=--no-experimental-permission && pnpm config set store-dir ${dockerInfo.pnpmStore || '/var/lib/blocklet/.pnpm-store'} --global && pnpm config set update-notifier false --global && pnpm install --shamefully-hoist --unsafe-perm --fetch-timeout=90000 --fetch-retries=5 || (echo "PNPM install Error, Retry with --force" && pnpm install --shamefully-hoist --unsafe-perm --fetch-timeout=90000 --fetch-retries=5 --force)`;
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
|
|
203
190
|
// Replace all occurrences of serverDir with baseDir in dockerEnv
|
|
204
191
|
let dockerEnvString = JSON.stringify(dockerEnv).replace(new RegExp(serverDir, 'g'), baseDir);
|
|
205
192
|
if (dockerEnv.BLOCKLET_DOCKER_NETWORK) {
|
|
@@ -220,12 +207,14 @@ async function parseDockerOptionsFromPm2({
|
|
|
220
207
|
let runScript = dockerInfo.script || '';
|
|
221
208
|
if (!runScript && dockerInfo.installNodeModules) {
|
|
222
209
|
const maxOldSpaceSize = Math.floor(Number(dockerEnv.BLOCKLET_DOCKER_MEMORY.replace('g', '')) * 0.85 * 1024);
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
210
|
+
const nodeInterpreter = `node ${process.env.ABT_NODE_BLOCKLET_MODE === ABT_NODE_KERNEL_OR_BLOCKLET_MODE.PERFORMANT ? '' : '--optimize_for_size'} --max-old-space-size=${maxOldSpaceSize} --max-http-header-size=16384 ${nextOptions.script} -- BLOCKLET_NAME=${options.name}`;
|
|
211
|
+
const bunInterpreter = `bun run ${nextOptions.script} -- BLOCKLET_NAME=${options.name}`;
|
|
212
|
+
const engine = getBlockletEngine(meta);
|
|
213
|
+
const runCommand = engine.interpreter === 'bun' ? bunInterpreter : nodeInterpreter;
|
|
214
|
+
runScript = /(npm|yarn|pnpm|bun)/g.test(nextOptions.script) ? nextOptions.script : runCommand;
|
|
226
215
|
}
|
|
227
216
|
|
|
228
|
-
const runScripts = ['preInstall', '
|
|
217
|
+
const runScripts = ['preInstall', 'postInstall', 'preFlight', 'preStart', '--runScript--']
|
|
229
218
|
.map((key) => {
|
|
230
219
|
if (key === '--runScript--') {
|
|
231
220
|
return overrideScript || runScript;
|
|
@@ -233,9 +222,6 @@ async function parseDockerOptionsFromPm2({
|
|
|
233
222
|
if (overrideScript) {
|
|
234
223
|
return '';
|
|
235
224
|
}
|
|
236
|
-
if (key === '--installScript--') {
|
|
237
|
-
return installScript;
|
|
238
|
-
}
|
|
239
225
|
return meta.scripts?.[key] || '';
|
|
240
226
|
})
|
|
241
227
|
.filter(Boolean);
|
|
@@ -283,9 +269,11 @@ async function parseDockerOptionsFromPm2({
|
|
|
283
269
|
{ source: nextOptions.env.BLOCKLET_LOG_DIR, target: dockerEnv.BLOCKLET_LOG_DIR, canEdit: true },
|
|
284
270
|
{ source: nextOptions.env.BLOCKLET_CACHE_DIR, target: dockerEnv.BLOCKLET_CACHE_DIR, canEdit: true },
|
|
285
271
|
{
|
|
286
|
-
source: path.join(nextOptions.env.BLOCKLET_APP_DIR,
|
|
272
|
+
source: path.join(nextOptions.env.BLOCKLET_APP_DIR, 'node_modules'),
|
|
287
273
|
target: path.join(dockerEnv.BLOCKLET_APP_DIR, 'node_modules'),
|
|
288
|
-
|
|
274
|
+
// 因为要共享 node_modules,而每个 node_modules 在 bin 和 pnpm 里都是硬链接, 编辑会有安全问题
|
|
275
|
+
// 上个版本能编辑是因为每个组件的 pnpm-store 都是独立的, 但是这样也使得每个组件首次安装的时间无法得到优化, 只有二次启动时才能用到缓存
|
|
276
|
+
canEdit: false,
|
|
289
277
|
},
|
|
290
278
|
{
|
|
291
279
|
source: path.join(nextOptions.env.BLOCKLET_APP_DATA_DIR, '.projects'),
|
|
@@ -297,20 +285,6 @@ async function parseDockerOptionsFromPm2({
|
|
|
297
285
|
target: dockerEnv.BLOCKLET_SHARE_DIR,
|
|
298
286
|
canEdit: true,
|
|
299
287
|
},
|
|
300
|
-
dockerInfo.pnpmStore && nextOptions.env.BLOCKLET_REAL_NAME && nextOptions.env.BLOCKLET_COMPONENT_DID
|
|
301
|
-
? {
|
|
302
|
-
source: path.join(
|
|
303
|
-
serverDir,
|
|
304
|
-
'tmp',
|
|
305
|
-
'pnpm-stores',
|
|
306
|
-
nextOptions.env.BLOCKLET_REAL_NAME.split('/')[1],
|
|
307
|
-
nextOptions.env.BLOCKLET_COMPONENT_DID,
|
|
308
|
-
'.pnpm-store'
|
|
309
|
-
),
|
|
310
|
-
target: dockerInfo.pnpmStore,
|
|
311
|
-
canEdit: true,
|
|
312
|
-
}
|
|
313
|
-
: null,
|
|
314
288
|
].filter((v) => {
|
|
315
289
|
if (!v) {
|
|
316
290
|
return false;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const { spawn } = require('child_process');
|
|
3
|
+
const fsp = require('fs/promises');
|
|
4
|
+
const os = require('os');
|
|
5
|
+
|
|
6
|
+
const BUN_VERSION = '1.2.18';
|
|
7
|
+
|
|
8
|
+
const getRootDir = () => {
|
|
9
|
+
if (process.env.ABT_NODE_DATA_DIR) {
|
|
10
|
+
return process.env.ABT_NODE_DATA_DIR;
|
|
11
|
+
}
|
|
12
|
+
return path.join(os.tmpdir(), 'bun_install');
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
async function _ensureBun() {
|
|
16
|
+
const bunDir = path.join(getRootDir(), 'core', 'bun_install');
|
|
17
|
+
try {
|
|
18
|
+
await fsp.access(bunDir);
|
|
19
|
+
} catch {
|
|
20
|
+
await fsp.mkdir(bunDir, { recursive: true });
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const installDir = path.join(bunDir, BUN_VERSION);
|
|
24
|
+
const binDir = path.join(installDir, 'bin');
|
|
25
|
+
const bunExec = path.join(binDir, process.platform === 'win32' ? 'bun.exe' : 'bun');
|
|
26
|
+
|
|
27
|
+
// If bun is already installed in this project, return its path
|
|
28
|
+
try {
|
|
29
|
+
await fsp.access(bunExec);
|
|
30
|
+
return bunExec;
|
|
31
|
+
} catch (_) {
|
|
32
|
+
//
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Create installation directory
|
|
36
|
+
await fsp.mkdir(installDir, { recursive: true });
|
|
37
|
+
|
|
38
|
+
// Run the official Bun installer script with BUN_INSTALL overridden
|
|
39
|
+
await new Promise((resolvePromise, reject) => {
|
|
40
|
+
const linuxInstall = ['-c', 'curl -fsSL https://bun.sh/install | bash'];
|
|
41
|
+
const windowsInstall = ['-c', 'powershell -c "irm bun.sh/install.ps1 | iex"'];
|
|
42
|
+
const installer = spawn('bash', process.platform === 'win32' ? windowsInstall : linuxInstall, {
|
|
43
|
+
env: { ...process.env, BUN_INSTALL: installDir, BUN_VERSION, SHELL: '/dev/null', HOME: installDir },
|
|
44
|
+
stdio: 'inherit',
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
installer.on('close', (code) => {
|
|
48
|
+
if (code !== 0) {
|
|
49
|
+
reject(new Error(`Bun installation failed with exit code ${code}`));
|
|
50
|
+
} else {
|
|
51
|
+
resolvePromise();
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
installer.on('error', (err) => {
|
|
56
|
+
reject(err);
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
return bunExec;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
let bunPathPromise = null;
|
|
64
|
+
|
|
65
|
+
// eslint-disable-next-line require-await
|
|
66
|
+
const ensureBun = async () => {
|
|
67
|
+
if (bunPathPromise) {
|
|
68
|
+
return bunPathPromise;
|
|
69
|
+
}
|
|
70
|
+
bunPathPromise = _ensureBun();
|
|
71
|
+
return bunPathPromise;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const bunOptions = {
|
|
75
|
+
baseDockerOs: 'Linux',
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const getBunCacheDir = async (isDocker = false) => {
|
|
79
|
+
const abtNodeDir = getRootDir();
|
|
80
|
+
// 如果不是linux, 缓存的目录区分 docker 和非 docker
|
|
81
|
+
let cacheDir = isDocker ? 'bun-cache-docker' : 'bun-cache';
|
|
82
|
+
if (os.type() === bunOptions.baseDockerOs) {
|
|
83
|
+
cacheDir = 'bun-cache';
|
|
84
|
+
}
|
|
85
|
+
const bunCacheDir = path.join(abtNodeDir, 'tmp', cacheDir);
|
|
86
|
+
try {
|
|
87
|
+
await fsp.access(bunCacheDir);
|
|
88
|
+
} catch (_) {
|
|
89
|
+
await fsp.mkdir(bunCacheDir, { recursive: true });
|
|
90
|
+
}
|
|
91
|
+
return bunCacheDir;
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
module.exports = { ensureBun, getBunCacheDir, BUN_VERSION, bunOptions };
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
const { spawn } = require('child_process');
|
|
2
2
|
const fs = require('fs-extra');
|
|
3
3
|
const path = require('path');
|
|
4
|
+
const { ensureBun, getBunCacheDir } = require('./ensure-bun');
|
|
5
|
+
const checkDockerRunHistory = require('./docker/check-docker-run-history');
|
|
6
|
+
const { dockerInstallDependencies, saveLastInstallOs, isSameOs } = require('./docker/docker-install-dependenices');
|
|
4
7
|
|
|
5
8
|
function isDependencyInstalled(appDir, dependency) {
|
|
6
9
|
return fs.existsSync(path.resolve(appDir, 'node_modules', dependency));
|
|
7
10
|
}
|
|
8
11
|
|
|
9
|
-
function installExternalDependencies({ appDir, forceInstall = false } = {}) {
|
|
12
|
+
async function installExternalDependencies({ appDir, forceInstall = false, nodeInfo } = {}) {
|
|
10
13
|
if (!appDir) {
|
|
11
14
|
throw new Error('appDir is required');
|
|
12
15
|
}
|
|
@@ -14,6 +17,12 @@ function installExternalDependencies({ appDir, forceInstall = false } = {}) {
|
|
|
14
17
|
throw new Error(`not a correct appDir directory: ${appDir}`);
|
|
15
18
|
}
|
|
16
19
|
|
|
20
|
+
const isUseDocker = checkDockerRunHistory(nodeInfo);
|
|
21
|
+
|
|
22
|
+
if (!(await isSameOs(appDir, isUseDocker))) {
|
|
23
|
+
fs.removeSync(path.join(appDir, 'node_modules'));
|
|
24
|
+
}
|
|
25
|
+
|
|
17
26
|
// 读取 BLOCKLET_APP_DIR 的 package.json
|
|
18
27
|
const packageJsonPath = path.resolve(appDir, 'package.json');
|
|
19
28
|
|
|
@@ -23,7 +32,7 @@ function installExternalDependencies({ appDir, forceInstall = false } = {}) {
|
|
|
23
32
|
|
|
24
33
|
const packageJson = fs.readJsonSync(packageJsonPath);
|
|
25
34
|
|
|
26
|
-
const { blockletExternalDependencies: externals = []
|
|
35
|
+
const { blockletExternalDependencies: externals = [] } = packageJson;
|
|
27
36
|
if (!Array.isArray(externals) || !externals.length) {
|
|
28
37
|
return;
|
|
29
38
|
}
|
|
@@ -33,35 +42,48 @@ function installExternalDependencies({ appDir, forceInstall = false } = {}) {
|
|
|
33
42
|
return;
|
|
34
43
|
}
|
|
35
44
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
const child = spawn(externalManager, ['install'], {
|
|
39
|
-
cwd: appDir,
|
|
40
|
-
stdio: 'pipe',
|
|
41
|
-
shell: true,
|
|
42
|
-
env: {
|
|
43
|
-
...process.env,
|
|
44
|
-
NODE_ENV: 'production',
|
|
45
|
-
},
|
|
46
|
-
});
|
|
45
|
+
const bunPath = await ensureBun();
|
|
46
|
+
const bunCacheDir = await getBunCacheDir();
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
if (isUseDocker) {
|
|
49
|
+
await dockerInstallDependencies({
|
|
50
|
+
// 用 appDir 后两个路径作为 docker name
|
|
51
|
+
name: appDir.split(path.sep).slice(-2).join(path.sep),
|
|
52
|
+
installDir: appDir,
|
|
51
53
|
});
|
|
54
|
+
} else {
|
|
55
|
+
await new Promise((resolve, reject) => {
|
|
56
|
+
const child = spawn(bunPath, ['install'], {
|
|
57
|
+
cwd: appDir,
|
|
58
|
+
stdio: 'pipe',
|
|
59
|
+
shell: true,
|
|
60
|
+
env: {
|
|
61
|
+
...process.env,
|
|
62
|
+
NODE_ENV: 'production',
|
|
63
|
+
BUN_INSTALL_CACHE_DIR: bunCacheDir,
|
|
64
|
+
},
|
|
65
|
+
});
|
|
52
66
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
67
|
+
let errorOutput = '';
|
|
68
|
+
child.stderr.on('data', (data) => {
|
|
69
|
+
errorOutput += data.toString();
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
child.on('close', (code) => {
|
|
73
|
+
if (code !== 0 && errorOutput.trim()) {
|
|
74
|
+
reject(new Error(errorOutput));
|
|
75
|
+
} else {
|
|
76
|
+
resolve();
|
|
77
|
+
}
|
|
78
|
+
});
|
|
60
79
|
|
|
61
|
-
|
|
62
|
-
|
|
80
|
+
child.on('error', (err) => {
|
|
81
|
+
reject(err);
|
|
82
|
+
});
|
|
63
83
|
});
|
|
64
|
-
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
await saveLastInstallOs(appDir, isUseDocker);
|
|
65
87
|
}
|
|
66
88
|
|
|
67
89
|
module.exports = { installExternalDependencies };
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "1.16.
|
|
6
|
+
"version": "1.16.47-beta-20250710-073736-01b9c1bc",
|
|
7
7
|
"description": "",
|
|
8
8
|
"main": "lib/index.js",
|
|
9
9
|
"files": [
|
|
@@ -19,22 +19,22 @@
|
|
|
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.
|
|
23
|
-
"@abtnode/auth": "1.16.
|
|
24
|
-
"@abtnode/certificate-manager": "1.16.
|
|
25
|
-
"@abtnode/client": "1.16.
|
|
26
|
-
"@abtnode/constant": "1.16.
|
|
27
|
-
"@abtnode/cron": "1.16.
|
|
28
|
-
"@abtnode/db-cache": "1.16.
|
|
29
|
-
"@abtnode/docker-utils": "1.16.
|
|
30
|
-
"@abtnode/logger": "1.16.
|
|
31
|
-
"@abtnode/models": "1.16.
|
|
32
|
-
"@abtnode/queue": "1.16.
|
|
33
|
-
"@abtnode/rbac": "1.16.
|
|
34
|
-
"@abtnode/router-provider": "1.16.
|
|
35
|
-
"@abtnode/static-server": "1.16.
|
|
36
|
-
"@abtnode/timemachine": "1.16.
|
|
37
|
-
"@abtnode/util": "1.16.
|
|
22
|
+
"@abtnode/analytics": "1.16.47-beta-20250710-073736-01b9c1bc",
|
|
23
|
+
"@abtnode/auth": "1.16.47-beta-20250710-073736-01b9c1bc",
|
|
24
|
+
"@abtnode/certificate-manager": "1.16.47-beta-20250710-073736-01b9c1bc",
|
|
25
|
+
"@abtnode/client": "1.16.47-beta-20250710-073736-01b9c1bc",
|
|
26
|
+
"@abtnode/constant": "1.16.47-beta-20250710-073736-01b9c1bc",
|
|
27
|
+
"@abtnode/cron": "1.16.47-beta-20250710-073736-01b9c1bc",
|
|
28
|
+
"@abtnode/db-cache": "1.16.47-beta-20250710-073736-01b9c1bc",
|
|
29
|
+
"@abtnode/docker-utils": "1.16.47-beta-20250710-073736-01b9c1bc",
|
|
30
|
+
"@abtnode/logger": "1.16.47-beta-20250710-073736-01b9c1bc",
|
|
31
|
+
"@abtnode/models": "1.16.47-beta-20250710-073736-01b9c1bc",
|
|
32
|
+
"@abtnode/queue": "1.16.47-beta-20250710-073736-01b9c1bc",
|
|
33
|
+
"@abtnode/rbac": "1.16.47-beta-20250710-073736-01b9c1bc",
|
|
34
|
+
"@abtnode/router-provider": "1.16.47-beta-20250710-073736-01b9c1bc",
|
|
35
|
+
"@abtnode/static-server": "1.16.47-beta-20250710-073736-01b9c1bc",
|
|
36
|
+
"@abtnode/timemachine": "1.16.47-beta-20250710-073736-01b9c1bc",
|
|
37
|
+
"@abtnode/util": "1.16.47-beta-20250710-073736-01b9c1bc",
|
|
38
38
|
"@arcblock/did": "1.20.15",
|
|
39
39
|
"@arcblock/did-auth": "1.20.15",
|
|
40
40
|
"@arcblock/did-ext": "1.20.15",
|
|
@@ -45,14 +45,14 @@
|
|
|
45
45
|
"@arcblock/pm2-events": "^0.0.5",
|
|
46
46
|
"@arcblock/validator": "1.20.15",
|
|
47
47
|
"@arcblock/vc": "1.20.15",
|
|
48
|
-
"@blocklet/constant": "1.16.
|
|
48
|
+
"@blocklet/constant": "1.16.47-beta-20250710-073736-01b9c1bc",
|
|
49
49
|
"@blocklet/did-space-js": "^1.1.5",
|
|
50
|
-
"@blocklet/env": "1.16.
|
|
50
|
+
"@blocklet/env": "1.16.47-beta-20250710-073736-01b9c1bc",
|
|
51
51
|
"@blocklet/error": "^0.2.5",
|
|
52
|
-
"@blocklet/meta": "1.16.
|
|
53
|
-
"@blocklet/resolver": "1.16.
|
|
54
|
-
"@blocklet/sdk": "1.16.
|
|
55
|
-
"@blocklet/store": "1.16.
|
|
52
|
+
"@blocklet/meta": "1.16.47-beta-20250710-073736-01b9c1bc",
|
|
53
|
+
"@blocklet/resolver": "1.16.47-beta-20250710-073736-01b9c1bc",
|
|
54
|
+
"@blocklet/sdk": "1.16.47-beta-20250710-073736-01b9c1bc",
|
|
55
|
+
"@blocklet/store": "1.16.47-beta-20250710-073736-01b9c1bc",
|
|
56
56
|
"@blocklet/theme": "^3.0.23",
|
|
57
57
|
"@fidm/x509": "^1.2.1",
|
|
58
58
|
"@ocap/mcrypto": "1.20.15",
|
|
@@ -116,5 +116,5 @@
|
|
|
116
116
|
"jest": "^29.7.0",
|
|
117
117
|
"unzipper": "^0.10.11"
|
|
118
118
|
},
|
|
119
|
-
"gitHead": "
|
|
119
|
+
"gitHead": "c43b4f2244b11ad072f32784adf35c435d29c3ca"
|
|
120
120
|
}
|