@abtnode/core 1.16.11-next-069c3537 → 1.16.11-next-3d2b39f7
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/node.js +1 -1
- package/lib/blocklet/downloader/blocklet-downloader.js +3 -3
- package/lib/blocklet/manager/disk.js +213 -136
- package/lib/blocklet/manager/helper/install-application-from-general.js +18 -3
- package/lib/blocklet/manager/helper/install-component-from-dev.js +0 -1
- package/lib/blocklet/manager/helper/install-component-from-upload.js +8 -4
- package/lib/blocklet/manager/helper/install-component-from-url.js +4 -2
- package/lib/blocklet/manager/helper/upgrade-components.js +7 -7
- package/lib/blocklet/manager/pm2-events.js +3 -3
- package/lib/event.js +11 -1
- package/lib/index.js +7 -3
- package/lib/migrations/1.16.11-component-status.js +22 -0
- package/lib/monitor/blocklet-runtime-monitor.js +3 -1
- package/lib/states/blocklet-extras.js +10 -0
- package/lib/states/blocklet.js +45 -38
- package/lib/states/node.js +1 -0
- package/lib/util/blocklet.js +116 -114
- package/lib/util/launcher.js +237 -0
- package/lib/validators/util.js +3 -0
- package/package.json +18 -18
|
@@ -38,6 +38,10 @@ const {
|
|
|
38
38
|
getRolesFromAuthConfig,
|
|
39
39
|
isInProgress,
|
|
40
40
|
isBeforeInstalled,
|
|
41
|
+
getComponentsInternalInfo,
|
|
42
|
+
forEachComponentV2,
|
|
43
|
+
forEachComponentV2Sync,
|
|
44
|
+
findComponentByIdV2,
|
|
41
45
|
} = require('@blocklet/meta/lib/util');
|
|
42
46
|
const getComponentProcessId = require('@blocklet/meta/lib/get-component-process-id');
|
|
43
47
|
const { update: updateMetaFile } = require('@blocklet/meta/lib/file');
|
|
@@ -49,6 +53,7 @@ const {
|
|
|
49
53
|
BlockletStatus,
|
|
50
54
|
BlockletSource,
|
|
51
55
|
BlockletEvents,
|
|
56
|
+
BlockletInternalEvents,
|
|
52
57
|
BLOCKLET_MODES,
|
|
53
58
|
BlockletGroup,
|
|
54
59
|
fromBlockletStatus,
|
|
@@ -66,6 +71,7 @@ const {
|
|
|
66
71
|
RESTORE_PROGRESS_STATUS,
|
|
67
72
|
CHAIN_PROP_MAP_REVERSE,
|
|
68
73
|
} = require('@blocklet/constant');
|
|
74
|
+
const { consumeServerlessNFT, consumeLauncherSession } = require('../../util/launcher');
|
|
69
75
|
const util = require('../../util');
|
|
70
76
|
const {
|
|
71
77
|
refresh: refreshAccessibleExternalNodeIp,
|
|
@@ -80,7 +86,6 @@ const {
|
|
|
80
86
|
stopBlockletProcess,
|
|
81
87
|
deleteBlockletProcess,
|
|
82
88
|
reloadBlockletProcess,
|
|
83
|
-
getBlockletStatusFromProcess,
|
|
84
89
|
checkBlockletProcessHealthy,
|
|
85
90
|
validateBlocklet,
|
|
86
91
|
validateBlockletChainInfo,
|
|
@@ -94,7 +99,6 @@ const {
|
|
|
94
99
|
getBlocklet,
|
|
95
100
|
ensureEnvDefault,
|
|
96
101
|
getConfigFromPreferences,
|
|
97
|
-
consumeServerlessNFT,
|
|
98
102
|
validateAppConfig,
|
|
99
103
|
checkDuplicateMountPoint,
|
|
100
104
|
validateStore,
|
|
@@ -104,6 +108,9 @@ const {
|
|
|
104
108
|
updateBlockletFallbackLogo,
|
|
105
109
|
ensureAppLogo,
|
|
106
110
|
getBlockletDidDomainList,
|
|
111
|
+
getProcessState,
|
|
112
|
+
getBlockletStatus,
|
|
113
|
+
shouldSkipComponent,
|
|
107
114
|
shouldCleanExpiredBlocklet,
|
|
108
115
|
} = require('../../util/blocklet');
|
|
109
116
|
const states = require('../../states');
|
|
@@ -133,7 +140,7 @@ const { migrateApplicationToStructV2 } = require('./helper/migrate-application-t
|
|
|
133
140
|
const { getBackupFilesUrlFromEndpoint, getBackupEndpoint } = require('../../util/spaces');
|
|
134
141
|
const { validateAddSpaceGateway, validateUpdateSpaceGateway } = require('../../validators/space-gateway');
|
|
135
142
|
|
|
136
|
-
const { formatEnvironments,
|
|
143
|
+
const { formatEnvironments, getBlockletMeta, validateOwner } = util;
|
|
137
144
|
|
|
138
145
|
const statusLock = new Lock('blocklet-status-lock');
|
|
139
146
|
|
|
@@ -239,8 +246,8 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
239
246
|
this._rollbackCache = new RollbackCache({ dir: this.dataDirs.tmp });
|
|
240
247
|
|
|
241
248
|
if (daemon) {
|
|
242
|
-
blockletPm2Events.on('online', (data) => this._syncPm2Status('online', data.blockletDid));
|
|
243
|
-
blockletPm2Events.on('stop', (data) => this._syncPm2Status('stop', data.blockletDid));
|
|
249
|
+
blockletPm2Events.on('online', (data) => this._syncPm2Status('online', data.blockletDid, data.componentDid));
|
|
250
|
+
blockletPm2Events.on('stop', (data) => this._syncPm2Status('stop', data.blockletDid, data.componentDid));
|
|
244
251
|
}
|
|
245
252
|
}
|
|
246
253
|
|
|
@@ -427,8 +434,8 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
427
434
|
return UpgradeComponents.check({ did, states });
|
|
428
435
|
}
|
|
429
436
|
|
|
430
|
-
async upgradeComponents({ updateId, selectedComponents:
|
|
431
|
-
return UpgradeComponents.upgrade({ updateId,
|
|
437
|
+
async upgradeComponents({ updateId, selectedComponents: componentDids }, context = {}) {
|
|
438
|
+
return UpgradeComponents.upgrade({ updateId, componentDids, context, states, manager: this });
|
|
432
439
|
}
|
|
433
440
|
|
|
434
441
|
async migrateApplicationToStructV2({ did, appSk, context = {} }) {
|
|
@@ -445,8 +452,8 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
445
452
|
return { did, isInstalled: !!blocklet, isRunning };
|
|
446
453
|
}
|
|
447
454
|
|
|
448
|
-
async start({ did, throwOnError, checkHealthImmediately = false, e2eMode = false }, context) {
|
|
449
|
-
logger.info('start blocklet', { did });
|
|
455
|
+
async start({ did, throwOnError, checkHealthImmediately = false, e2eMode = false, componentDids }, context) {
|
|
456
|
+
logger.info('start blocklet', { did, componentDids, throwOnError, checkHealthImmediately, e2eMode });
|
|
450
457
|
// should check blocklet integrity
|
|
451
458
|
const blocklet = await this.ensureBlocklet(did, { e2eMode });
|
|
452
459
|
|
|
@@ -454,7 +461,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
454
461
|
// blocklet may be manually stopped durning starting
|
|
455
462
|
// so error message would not be sent if blocklet is stopped
|
|
456
463
|
// so we need update status first
|
|
457
|
-
await states.blocklet.setBlockletStatus(did, BlockletStatus.starting);
|
|
464
|
+
await states.blocklet.setBlockletStatus(did, BlockletStatus.starting, { componentDids });
|
|
458
465
|
blocklet.status = BlockletStatus.starting;
|
|
459
466
|
|
|
460
467
|
// validate requirement and engine
|
|
@@ -507,6 +514,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
507
514
|
nodeEnvironments,
|
|
508
515
|
nodeInfo: await states.node.read(),
|
|
509
516
|
e2eMode,
|
|
517
|
+
componentDids,
|
|
510
518
|
});
|
|
511
519
|
|
|
512
520
|
// check blocklet healthy
|
|
@@ -516,6 +524,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
516
524
|
context,
|
|
517
525
|
minConsecutiveTime,
|
|
518
526
|
timeout: startTimeout,
|
|
527
|
+
componentDids,
|
|
519
528
|
};
|
|
520
529
|
|
|
521
530
|
if (checkHealthImmediately) {
|
|
@@ -548,8 +557,8 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
548
557
|
severity: 'error',
|
|
549
558
|
});
|
|
550
559
|
|
|
551
|
-
await this.deleteProcess({ did });
|
|
552
|
-
const res = await states.blocklet.setBlockletStatus(did, BlockletStatus.error);
|
|
560
|
+
await this.deleteProcess({ did, componentDids });
|
|
561
|
+
const res = await states.blocklet.setBlockletStatus(did, BlockletStatus.error, { componentDids });
|
|
553
562
|
this.emit(BlockletEvents.startFailed, { ...res, error: { message: error.message } });
|
|
554
563
|
|
|
555
564
|
if (throwOnError) {
|
|
@@ -560,14 +569,14 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
560
569
|
}
|
|
561
570
|
}
|
|
562
571
|
|
|
563
|
-
async stop({ did, updateStatus = true, silent = false }, context) {
|
|
564
|
-
logger.info('stop blocklet', { did });
|
|
572
|
+
async stop({ did, updateStatus = true, silent = false, componentDids }, context) {
|
|
573
|
+
logger.info('stop blocklet', { did, componentDids, updateStatus, silent });
|
|
565
574
|
|
|
566
575
|
const blocklet = await this.getBlocklet(did);
|
|
567
576
|
const { processId } = blocklet.env;
|
|
568
577
|
|
|
569
578
|
if (updateStatus) {
|
|
570
|
-
await states.blocklet.setBlockletStatus(did, BlockletStatus.stopping);
|
|
579
|
+
await states.blocklet.setBlockletStatus(did, BlockletStatus.stopping, { componentDids });
|
|
571
580
|
blocklet.status = BlockletStatus.stopping;
|
|
572
581
|
this.emit(BlockletEvents.statusChange, blocklet);
|
|
573
582
|
}
|
|
@@ -587,11 +596,12 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
587
596
|
silent,
|
|
588
597
|
...getHooksOutputFiles(b),
|
|
589
598
|
}),
|
|
599
|
+
componentDids,
|
|
590
600
|
});
|
|
591
601
|
} catch (error) {
|
|
592
602
|
logger.error('Failed to stop blocklet', { error, did });
|
|
593
603
|
if (updateStatus) {
|
|
594
|
-
const res = await states.blocklet.setBlockletStatus(did, BlockletStatus.error);
|
|
604
|
+
const res = await states.blocklet.setBlockletStatus(did, BlockletStatus.error, { componentDids });
|
|
595
605
|
this.emit(BlockletEvents.statusChange, res);
|
|
596
606
|
}
|
|
597
607
|
throw error;
|
|
@@ -600,13 +610,18 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
600
610
|
logger.info('blocklet stopped successfully', { processId, did });
|
|
601
611
|
|
|
602
612
|
if (updateStatus) {
|
|
603
|
-
const res = await states.blocklet.setBlockletStatus(did, BlockletStatus.stopped);
|
|
613
|
+
const res = await states.blocklet.setBlockletStatus(did, BlockletStatus.stopped, { componentDids });
|
|
604
614
|
// send notification to websocket channel
|
|
605
615
|
this.emit(BlockletEvents.statusChange, res);
|
|
606
616
|
|
|
607
617
|
// send notification to wallet
|
|
608
618
|
this.emit(BlockletEvents.stopped, res);
|
|
609
619
|
|
|
620
|
+
this.emit(BlockletInternalEvents.componentsUpdated, {
|
|
621
|
+
appDid: blocklet.appDid,
|
|
622
|
+
components: getComponentsInternalInfo(res),
|
|
623
|
+
});
|
|
624
|
+
|
|
610
625
|
return res;
|
|
611
626
|
}
|
|
612
627
|
|
|
@@ -660,18 +675,25 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
660
675
|
* @param {Record<string, any>} context
|
|
661
676
|
* @returns {import('@abtnode/client').BlockletState}
|
|
662
677
|
*/
|
|
663
|
-
async restart({ did }, context) {
|
|
678
|
+
async restart({ did, componentDids }, context) {
|
|
664
679
|
logger.info('restart blocklet', { did });
|
|
665
680
|
|
|
666
|
-
await states.blocklet.setBlockletStatus(did, BlockletStatus.stopping);
|
|
681
|
+
await states.blocklet.setBlockletStatus(did, BlockletStatus.stopping, { componentDids });
|
|
667
682
|
const result = await states.blocklet.getBlocklet(did);
|
|
668
683
|
this.emit(BlockletEvents.statusChange, result);
|
|
669
684
|
|
|
670
|
-
const ticket = this.startQueue.push({
|
|
685
|
+
const ticket = this.startQueue.push({
|
|
686
|
+
entity: 'blocklet',
|
|
687
|
+
action: 'restart',
|
|
688
|
+
id: did,
|
|
689
|
+
did,
|
|
690
|
+
componentDids,
|
|
691
|
+
context,
|
|
692
|
+
});
|
|
671
693
|
ticket.on('failed', async (err) => {
|
|
672
694
|
logger.error('failed to restart blocklet', { did, error: err });
|
|
673
695
|
|
|
674
|
-
const state = await states.blocklet.setBlockletStatus(did, BlockletStatus.stopped);
|
|
696
|
+
const state = await states.blocklet.setBlockletStatus(did, BlockletStatus.stopped, { componentDids });
|
|
675
697
|
this.emit(BlockletEvents.statusChange, state);
|
|
676
698
|
|
|
677
699
|
this._createNotification(did, {
|
|
@@ -687,16 +709,28 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
687
709
|
}
|
|
688
710
|
|
|
689
711
|
// eslint-disable-next-line no-unused-vars
|
|
690
|
-
async reload({ did }, context) {
|
|
712
|
+
async reload({ did, componentDids: list }, context) {
|
|
691
713
|
const blocklet = await this.getBlocklet(did);
|
|
692
714
|
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
715
|
+
const componentDids = (blocklet.children || [])
|
|
716
|
+
.filter((x) => x.status === BlockletStatus.running)
|
|
717
|
+
.filter((x) => !shouldSkipComponent(x.meta.did, list))
|
|
718
|
+
.map((x) => x.meta.did);
|
|
697
719
|
|
|
698
|
-
|
|
699
|
-
|
|
720
|
+
if (!componentDids.length) {
|
|
721
|
+
throw new Error('No running component found');
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
try {
|
|
725
|
+
await reloadBlockletProcess(blocklet, { componentDids });
|
|
726
|
+
const res = await states.blocklet.setBlockletStatus(did, BlockletStatus.running, { componentDids });
|
|
727
|
+
logger.info('blocklet reload successfully', { did, componentDids });
|
|
728
|
+
this.emit(BlockletEvents.statusChange, res);
|
|
729
|
+
return res;
|
|
730
|
+
} catch (error) {
|
|
731
|
+
logger.error('Failed to reload blocklet', { error, did, componentDids });
|
|
732
|
+
throw error;
|
|
733
|
+
}
|
|
700
734
|
}
|
|
701
735
|
|
|
702
736
|
async delete({ did, keepData, keepLogsDir, keepConfigs }, context) {
|
|
@@ -755,17 +789,17 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
755
789
|
|
|
756
790
|
const blocklet = await this.getBlocklet(did);
|
|
757
791
|
|
|
758
|
-
if (
|
|
759
|
-
|
|
760
|
-
|
|
792
|
+
if (!childDid) {
|
|
793
|
+
if (isInProgress(blocklet.status || blocklet.status === BlockletStatus.running)) {
|
|
794
|
+
throw new Error('Cannot reset when blocklet is in progress');
|
|
795
|
+
}
|
|
761
796
|
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
797
|
+
try {
|
|
798
|
+
await this.deleteProcess({ did }, context);
|
|
799
|
+
} catch {
|
|
800
|
+
// do nothing
|
|
801
|
+
}
|
|
767
802
|
|
|
768
|
-
if (!childDid) {
|
|
769
803
|
// Cleanup disk storage
|
|
770
804
|
const { cacheDir, logsDir, dataDir } = blocklet.env;
|
|
771
805
|
fs.removeSync(cacheDir);
|
|
@@ -783,6 +817,16 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
783
817
|
throw new Error('Child does not exist');
|
|
784
818
|
}
|
|
785
819
|
|
|
820
|
+
if (isInProgress(child.status || child.status === BlockletStatus.running)) {
|
|
821
|
+
throw new Error('Cannot reset when component is in progress');
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
try {
|
|
825
|
+
await this.deleteProcess({ did, componentDids: [child.meta.did] }, context);
|
|
826
|
+
} catch {
|
|
827
|
+
// do nothing
|
|
828
|
+
}
|
|
829
|
+
|
|
786
830
|
// Cleanup disk storage
|
|
787
831
|
const { cacheDir, logsDir, dataDir } = child.env;
|
|
788
832
|
fs.removeSync(cacheDir);
|
|
@@ -864,6 +908,11 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
864
908
|
action: `/blocklets/${newBlocklet.meta.did}/components`,
|
|
865
909
|
});
|
|
866
910
|
|
|
911
|
+
this.emit(BlockletInternalEvents.componentsUpdated, {
|
|
912
|
+
appDid: blocklet.appDid,
|
|
913
|
+
components: getComponentsInternalInfo(newBlocklet),
|
|
914
|
+
});
|
|
915
|
+
|
|
867
916
|
return newBlocklet;
|
|
868
917
|
}
|
|
869
918
|
|
|
@@ -922,7 +971,14 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
922
971
|
// fallback blocklet status to error
|
|
923
972
|
const blocklet = await states.blocklet.getBlocklet(inputDid);
|
|
924
973
|
if (blocklet) {
|
|
925
|
-
|
|
974
|
+
const componentDids = [];
|
|
975
|
+
forEachComponentV2Sync(blocklet, (x) => {
|
|
976
|
+
if ([BlockletStatus.waiting, BlockletStatus.downloading].includes(x.status)) {
|
|
977
|
+
componentDids.push(x.meta.did);
|
|
978
|
+
}
|
|
979
|
+
});
|
|
980
|
+
|
|
981
|
+
await states.blocklet.setBlockletStatus(blocklet.meta.did, BlockletStatus.error, { componentDids });
|
|
926
982
|
}
|
|
927
983
|
statusLock.release();
|
|
928
984
|
} catch (err) {
|
|
@@ -935,15 +991,15 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
935
991
|
}
|
|
936
992
|
|
|
937
993
|
// eslint-disable-next-line no-unused-vars
|
|
938
|
-
async deleteProcess({ did }, context) {
|
|
994
|
+
async deleteProcess({ did, componentDids }, context) {
|
|
939
995
|
const blocklet = await this.getBlocklet(did);
|
|
940
996
|
|
|
941
|
-
logger.info('delete blocklet process', { did });
|
|
997
|
+
logger.info('delete blocklet process', { did, componentDids });
|
|
942
998
|
|
|
943
|
-
await deleteBlockletProcess(blocklet, context);
|
|
999
|
+
await deleteBlockletProcess(blocklet, { ...context, componentDids });
|
|
944
1000
|
|
|
945
|
-
const result = await states.blocklet.setBlockletStatus(did, BlockletStatus.stopped);
|
|
946
|
-
logger.info('blocklet process deleted successfully', { did });
|
|
1001
|
+
const result = await states.blocklet.setBlockletStatus(did, BlockletStatus.stopped, { componentDids });
|
|
1002
|
+
logger.info('blocklet process deleted successfully', { did, componentDids });
|
|
947
1003
|
return result;
|
|
948
1004
|
}
|
|
949
1005
|
|
|
@@ -1021,19 +1077,18 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1021
1077
|
}
|
|
1022
1078
|
|
|
1023
1079
|
const tmpDids = Array.isArray(did) ? did : [did];
|
|
1024
|
-
const [rootDid,
|
|
1080
|
+
const [rootDid, childDid] = tmpDids;
|
|
1025
1081
|
const rootMetaDid = await states.blocklet.getBlockletMetaDid(rootDid);
|
|
1026
|
-
const dids = [rootMetaDid, ...childDids];
|
|
1027
1082
|
|
|
1028
|
-
logger.info('config blocklet', {
|
|
1083
|
+
logger.info('config blocklet', { rootDid, rootMetaDid, childDid });
|
|
1029
1084
|
|
|
1030
1085
|
const ancestors = [];
|
|
1031
1086
|
let blocklet = await this.getBlocklet(rootDid);
|
|
1032
|
-
|
|
1087
|
+
if (childDid) {
|
|
1033
1088
|
ancestors.push(blocklet);
|
|
1034
1089
|
blocklet = blocklet.children.find((x) => x.meta.did === childDid);
|
|
1035
1090
|
if (!blocklet) {
|
|
1036
|
-
throw new Error('Child blocklet does not exist', {
|
|
1091
|
+
throw new Error('Child blocklet does not exist', { rootDid, childDid });
|
|
1037
1092
|
}
|
|
1038
1093
|
}
|
|
1039
1094
|
|
|
@@ -1046,8 +1101,8 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1046
1101
|
await environmentNameSchema.validateAsync(x.key);
|
|
1047
1102
|
} else if (BLOCKLET_CONFIGURABLE_KEY[x.key] && x.key.startsWith('BLOCKLET_')) {
|
|
1048
1103
|
// app key
|
|
1049
|
-
if (
|
|
1050
|
-
logger.error(`Cannot set ${x.key} to child blocklet`,
|
|
1104
|
+
if (childDid) {
|
|
1105
|
+
logger.error(`Cannot set ${x.key} to child blocklet`, { rootDid, childDid });
|
|
1051
1106
|
throw new Error(`Cannot set ${x.key} to child blocklet`);
|
|
1052
1107
|
}
|
|
1053
1108
|
await validateAppConfig(x, states);
|
|
@@ -1086,7 +1141,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1086
1141
|
Object.assign(blocklet.configObj, configObj);
|
|
1087
1142
|
|
|
1088
1143
|
// update db
|
|
1089
|
-
await states.blockletExtras.setConfigs(
|
|
1144
|
+
await states.blockletExtras.setConfigs([rootMetaDid, childDid].filter(Boolean), newConfigs);
|
|
1090
1145
|
|
|
1091
1146
|
if (willAppSkChange) {
|
|
1092
1147
|
const info = await states.node.read();
|
|
@@ -1106,7 +1161,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1106
1161
|
}
|
|
1107
1162
|
|
|
1108
1163
|
// update blocklet meta
|
|
1109
|
-
if (blocklet.structVersion && !
|
|
1164
|
+
if (blocklet.structVersion && !childDid) {
|
|
1110
1165
|
const changedTitle = newConfigs.find((x) => x.key === BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_APP_NAME)?.value;
|
|
1111
1166
|
const changedDescription = newConfigs.find(
|
|
1112
1167
|
(x) => x.key === BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_APP_DESCRIPTION
|
|
@@ -1135,6 +1190,13 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1135
1190
|
await this._updateDidDocument(newState);
|
|
1136
1191
|
}
|
|
1137
1192
|
|
|
1193
|
+
if (!childDid && !newConfigs.some((x) => x.key === BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_APP_SK)) {
|
|
1194
|
+
this.emit(BlockletInternalEvents.appConfigChanged, {
|
|
1195
|
+
appDid: newState.appDid,
|
|
1196
|
+
configs: newConfigs.map((x) => ({ key: x.key, value: x.value })),
|
|
1197
|
+
});
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1138
1200
|
this.emit(BlockletEvents.updated, newState);
|
|
1139
1201
|
|
|
1140
1202
|
return newState;
|
|
@@ -1311,6 +1373,10 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1311
1373
|
await states.blocklet.updateBlocklet(rootDid, { mountPoint: blocklet.mountPoint, children: blocklet.children });
|
|
1312
1374
|
|
|
1313
1375
|
this.emit(BlockletEvents.upgraded, { blocklet, context: { ...context, createAuditLog: false } }); // trigger router refresh
|
|
1376
|
+
this.emit(BlockletInternalEvents.componentsUpdated, {
|
|
1377
|
+
appDid: blocklet.appDid,
|
|
1378
|
+
components: getComponentsInternalInfo(blocklet),
|
|
1379
|
+
});
|
|
1314
1380
|
|
|
1315
1381
|
return this.getBlocklet(rootDid);
|
|
1316
1382
|
}
|
|
@@ -1369,57 +1435,40 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1369
1435
|
return this.getBlocklet(did);
|
|
1370
1436
|
}
|
|
1371
1437
|
|
|
1372
|
-
async status(did, { forceSync = false } = {}) {
|
|
1373
|
-
const fastReturnOnForceSync = async (blocklet = {}) => {
|
|
1374
|
-
const { status } = blocklet;
|
|
1375
|
-
const { added, waiting, downloading, installing, installed, upgrading } = BlockletStatus;
|
|
1376
|
-
|
|
1377
|
-
if ([added, waiting, downloading, installing, installed, upgrading].includes(status)) {
|
|
1378
|
-
return blocklet;
|
|
1379
|
-
}
|
|
1380
|
-
|
|
1381
|
-
const res = await states.blocklet.setBlockletStatus(did, BlockletStatus.stopped);
|
|
1382
|
-
this.emit(BlockletEvents.statusChange, res);
|
|
1383
|
-
return res;
|
|
1384
|
-
};
|
|
1385
|
-
|
|
1438
|
+
async status(did, { forceSync = false, componentDids } = {}) {
|
|
1386
1439
|
const blocklet = await this.getBlocklet(did);
|
|
1387
1440
|
|
|
1388
|
-
|
|
1389
|
-
if (
|
|
1390
|
-
const uptime = Date.now() - new Date(blocklet.updatedAt).getTime();
|
|
1391
|
-
// FIXME @linchen 在彻底修复 blocklet status 稳定性之后, uptime check 应该去掉. 如果 hook 执行时间很长, uptime check 会影响 hook 执行过程中的 blocklet status
|
|
1392
|
-
if (uptime > 120 * 1000) {
|
|
1393
|
-
shouldUpdateStatus = true;
|
|
1394
|
-
}
|
|
1395
|
-
}
|
|
1396
|
-
|
|
1397
|
-
if (!shouldUpdateStatus) {
|
|
1441
|
+
// for backward compatibility
|
|
1442
|
+
if (!blocklet.structVersion) {
|
|
1398
1443
|
return blocklet;
|
|
1399
1444
|
}
|
|
1400
1445
|
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
!
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
const res = await states.blocklet.setBlockletStatus(did, BlockletStatus.stopped);
|
|
1408
|
-
this.emit(BlockletEvents.statusChange, res);
|
|
1409
|
-
return res;
|
|
1410
|
-
}
|
|
1446
|
+
await forEachComponentV2(
|
|
1447
|
+
blocklet,
|
|
1448
|
+
async (component) => {
|
|
1449
|
+
if (!forceSync || !isInProgress(component.status)) {
|
|
1450
|
+
return;
|
|
1451
|
+
}
|
|
1411
1452
|
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
this.emit(BlockletEvents.statusChange, res);
|
|
1416
|
-
return res;
|
|
1417
|
-
}
|
|
1453
|
+
if (shouldSkipComponent(component.meta.did, componentDids)) {
|
|
1454
|
+
return;
|
|
1455
|
+
}
|
|
1418
1456
|
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1457
|
+
try {
|
|
1458
|
+
const status = await getProcessState(component.env.processId);
|
|
1459
|
+
if (component.status !== status) {
|
|
1460
|
+
await states.blocklet.setBlockletStatus(did, status, { componentDids: [component.meta.did] });
|
|
1461
|
+
}
|
|
1462
|
+
} catch {
|
|
1463
|
+
// do nothing
|
|
1464
|
+
}
|
|
1465
|
+
},
|
|
1466
|
+
{ parallel: true }
|
|
1467
|
+
);
|
|
1468
|
+
|
|
1469
|
+
blocklet.status = getBlockletStatus(blocklet);
|
|
1470
|
+
|
|
1471
|
+
return blocklet;
|
|
1423
1472
|
}
|
|
1424
1473
|
|
|
1425
1474
|
async refreshListCache() {
|
|
@@ -1636,7 +1685,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1636
1685
|
* oldBlocklet: {},
|
|
1637
1686
|
* throwOnError: Error,
|
|
1638
1687
|
* skipCheckStatusBeforeDownload: boolean,
|
|
1639
|
-
*
|
|
1688
|
+
* componentDids: Array<did>,
|
|
1640
1689
|
* }} params
|
|
1641
1690
|
* @return {*}
|
|
1642
1691
|
* @memberof BlockletManager
|
|
@@ -1649,7 +1698,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1649
1698
|
oldBlocklet,
|
|
1650
1699
|
throwOnError,
|
|
1651
1700
|
skipCheckStatusBeforeDownload,
|
|
1652
|
-
|
|
1701
|
+
componentDids,
|
|
1653
1702
|
skipCheckIntegrity,
|
|
1654
1703
|
} = params;
|
|
1655
1704
|
const { meta } = blocklet;
|
|
@@ -1686,8 +1735,8 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1686
1735
|
const blockletForDownload = {
|
|
1687
1736
|
...blocklet,
|
|
1688
1737
|
children: (blocklet.children || []).filter((x) => {
|
|
1689
|
-
if (
|
|
1690
|
-
return
|
|
1738
|
+
if (componentDids?.length) {
|
|
1739
|
+
return componentDids.includes(x.meta.did);
|
|
1691
1740
|
}
|
|
1692
1741
|
return x;
|
|
1693
1742
|
}),
|
|
@@ -1758,12 +1807,12 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1758
1807
|
}
|
|
1759
1808
|
|
|
1760
1809
|
if (postAction === 'install') {
|
|
1761
|
-
const state = await states.blocklet.setBlockletStatus(did, BlockletStatus.installing);
|
|
1810
|
+
const state = await states.blocklet.setBlockletStatus(did, BlockletStatus.installing, { componentDids });
|
|
1762
1811
|
this.emit(BlockletEvents.statusChange, state);
|
|
1763
1812
|
}
|
|
1764
1813
|
|
|
1765
1814
|
if (postAction === 'upgrade') {
|
|
1766
|
-
const state = await states.blocklet.setBlockletStatus(did, BlockletStatus.upgrading);
|
|
1815
|
+
const state = await states.blocklet.setBlockletStatus(did, BlockletStatus.upgrading, { componentDids });
|
|
1767
1816
|
this.emit(BlockletEvents.statusChange, state);
|
|
1768
1817
|
}
|
|
1769
1818
|
|
|
@@ -1777,13 +1826,13 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1777
1826
|
try {
|
|
1778
1827
|
// install blocklet
|
|
1779
1828
|
if (postAction === 'install') {
|
|
1780
|
-
await this._onInstall({ blocklet, context, oldBlocklet });
|
|
1829
|
+
await this._onInstall({ blocklet, componentDids, context, oldBlocklet });
|
|
1781
1830
|
return;
|
|
1782
1831
|
}
|
|
1783
1832
|
|
|
1784
1833
|
// upgrade blocklet
|
|
1785
1834
|
if (postAction === 'upgrade') {
|
|
1786
|
-
await this._onUpgrade({ oldBlocklet, newBlocklet: blocklet, context });
|
|
1835
|
+
await this._onUpgrade({ oldBlocklet, componentDids, newBlocklet: blocklet, context });
|
|
1787
1836
|
}
|
|
1788
1837
|
} catch (error) {
|
|
1789
1838
|
if (throwOnError) {
|
|
@@ -1792,7 +1841,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1792
1841
|
}
|
|
1793
1842
|
}
|
|
1794
1843
|
|
|
1795
|
-
async _onInstall({ blocklet, context, oldBlocklet }) {
|
|
1844
|
+
async _onInstall({ blocklet, componentDids, context, oldBlocklet }) {
|
|
1796
1845
|
const { meta } = blocklet;
|
|
1797
1846
|
const { did, version } = meta;
|
|
1798
1847
|
logger.info('do install blocklet', { did, version });
|
|
@@ -1800,6 +1849,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1800
1849
|
try {
|
|
1801
1850
|
const installedBlocklet = await this._installBlocklet({
|
|
1802
1851
|
did,
|
|
1852
|
+
componentDids,
|
|
1803
1853
|
context,
|
|
1804
1854
|
oldBlocklet,
|
|
1805
1855
|
});
|
|
@@ -1807,7 +1857,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1807
1857
|
if (context.startImmediately && installedBlocklet?.settings.initialized) {
|
|
1808
1858
|
try {
|
|
1809
1859
|
logger.info('start blocklet after installed', { did });
|
|
1810
|
-
await this.start({ did, checkHealthImmediately: true });
|
|
1860
|
+
await this.start({ did, checkHealthImmediately: true, componentDids });
|
|
1811
1861
|
} catch (error) {
|
|
1812
1862
|
logger.warn('attempt to start immediately failed', { did, error });
|
|
1813
1863
|
}
|
|
@@ -1820,7 +1870,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1820
1870
|
}
|
|
1821
1871
|
}
|
|
1822
1872
|
|
|
1823
|
-
async _onUpgrade({ oldBlocklet, newBlocklet, context }) {
|
|
1873
|
+
async _onUpgrade({ oldBlocklet, newBlocklet, componentDids, context }) {
|
|
1824
1874
|
const { version, did } = newBlocklet.meta;
|
|
1825
1875
|
logger.info('do upgrade blocklet', { did, version });
|
|
1826
1876
|
|
|
@@ -1828,6 +1878,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1828
1878
|
await this._upgradeBlocklet({
|
|
1829
1879
|
newBlocklet,
|
|
1830
1880
|
oldBlocklet,
|
|
1881
|
+
componentDids,
|
|
1831
1882
|
context,
|
|
1832
1883
|
});
|
|
1833
1884
|
} catch (err) {
|
|
@@ -1835,13 +1886,13 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1835
1886
|
}
|
|
1836
1887
|
}
|
|
1837
1888
|
|
|
1838
|
-
async _onRestart({ did, context }) {
|
|
1839
|
-
await this.stop({ did, updateStatus: false }, context);
|
|
1840
|
-
await this.start({ did }, context);
|
|
1889
|
+
async _onRestart({ did, componentDids, context }) {
|
|
1890
|
+
await this.stop({ did, componentDids, updateStatus: false }, context);
|
|
1891
|
+
await this.start({ did, componentDids }, context);
|
|
1841
1892
|
}
|
|
1842
1893
|
|
|
1843
1894
|
async _onCheckIfStarted(jobInfo, { throwOnError } = {}) {
|
|
1844
|
-
const { did, context, minConsecutiveTime = 5000, timeout } = jobInfo;
|
|
1895
|
+
const { did, context, minConsecutiveTime = 5000, timeout, componentDids } = jobInfo;
|
|
1845
1896
|
const blocklet = await this.getBlocklet(did);
|
|
1846
1897
|
|
|
1847
1898
|
const { meta } = blocklet;
|
|
@@ -1849,10 +1900,18 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1849
1900
|
|
|
1850
1901
|
try {
|
|
1851
1902
|
// healthy check
|
|
1852
|
-
await checkBlockletProcessHealthy(blocklet, { minConsecutiveTime, timeout });
|
|
1903
|
+
await checkBlockletProcessHealthy(blocklet, { minConsecutiveTime, timeout, componentDids });
|
|
1853
1904
|
|
|
1854
1905
|
// update blocklet status after healthy check
|
|
1855
|
-
|
|
1906
|
+
await states.blocklet.setBlockletStatus(did, BlockletStatus.running, { componentDids });
|
|
1907
|
+
|
|
1908
|
+
const res = await this.getBlocklet(did);
|
|
1909
|
+
|
|
1910
|
+
this.emit(BlockletInternalEvents.componentsUpdated, {
|
|
1911
|
+
appDid: blocklet.appDid,
|
|
1912
|
+
components: getComponentsInternalInfo(res),
|
|
1913
|
+
});
|
|
1914
|
+
|
|
1856
1915
|
this.emit(BlockletEvents.started, res);
|
|
1857
1916
|
} catch (error) {
|
|
1858
1917
|
const status = await states.blocklet.getBlockletStatus(did);
|
|
@@ -1864,7 +1923,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1864
1923
|
logger.error('check blocklet if started failed', { did, name, context, timeout, error });
|
|
1865
1924
|
|
|
1866
1925
|
await this.deleteProcess({ did }, context);
|
|
1867
|
-
await states.blocklet.setBlockletStatus(did, BlockletStatus.error);
|
|
1926
|
+
await states.blocklet.setBlockletStatus(did, BlockletStatus.error, { componentDids });
|
|
1868
1927
|
|
|
1869
1928
|
this._createNotification(did, {
|
|
1870
1929
|
title: 'Blocklet Start Failed',
|
|
@@ -2256,7 +2315,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2256
2315
|
* @param {string} opt.did
|
|
2257
2316
|
* @param {object} opt.context
|
|
2258
2317
|
*/
|
|
2259
|
-
async _installBlocklet({ did, oldBlocklet, context, createNotification = true }) {
|
|
2318
|
+
async _installBlocklet({ did, oldBlocklet, componentDids, context, createNotification = true }) {
|
|
2260
2319
|
try {
|
|
2261
2320
|
// should ensure blocklet integrity
|
|
2262
2321
|
let blocklet = await this.ensureBlocklet(did);
|
|
@@ -2280,7 +2339,9 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2280
2339
|
// post install
|
|
2281
2340
|
await this._runPostInstallHook(blocklet, context);
|
|
2282
2341
|
|
|
2283
|
-
await states.blocklet.
|
|
2342
|
+
await states.blocklet.setInstalledAt(did);
|
|
2343
|
+
|
|
2344
|
+
await states.blocklet.setBlockletStatus(did, BlockletStatus.installed, { componentDids });
|
|
2284
2345
|
blocklet = await this.getBlocklet(did);
|
|
2285
2346
|
logger.info('blocklet installed', { source, did: meta.did });
|
|
2286
2347
|
|
|
@@ -2308,14 +2369,22 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2308
2369
|
});
|
|
2309
2370
|
}
|
|
2310
2371
|
|
|
2311
|
-
if (blocklet
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
})
|
|
2372
|
+
if (blocklet.controller && process.env.NODE_ENV !== 'test') {
|
|
2373
|
+
let isNFTConsumed = false;
|
|
2374
|
+
if (blocklet.controller.launcherSessionId && blocklet.controller.launcherUrl) {
|
|
2375
|
+
await consumeLauncherSession({ params: blocklet.controller, blocklet });
|
|
2376
|
+
isNFTConsumed = true;
|
|
2377
|
+
} else if (blocklet.controller.nftId) {
|
|
2378
|
+
await consumeServerlessNFT({ nftId: blocklet.controller.nftId, blocklet });
|
|
2379
|
+
isNFTConsumed = true;
|
|
2380
|
+
}
|
|
2317
2381
|
|
|
2318
|
-
|
|
2382
|
+
if (isNFTConsumed) {
|
|
2383
|
+
await states.blockletExtras.updateByDid(did, {
|
|
2384
|
+
controller: { ...blocklet.controller, consumedAt: new Date().toISOString() },
|
|
2385
|
+
});
|
|
2386
|
+
this.emit(BlockletEvents.nftConsumed, { blocklet, context });
|
|
2387
|
+
}
|
|
2319
2388
|
}
|
|
2320
2389
|
|
|
2321
2390
|
if (createNotification) {
|
|
@@ -2361,7 +2430,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2361
2430
|
}
|
|
2362
2431
|
}
|
|
2363
2432
|
|
|
2364
|
-
async _upgradeBlocklet({ newBlocklet, oldBlocklet, context = {} }) {
|
|
2433
|
+
async _upgradeBlocklet({ newBlocklet, oldBlocklet, componentDids, context = {} }) {
|
|
2365
2434
|
const { meta, source, deployedFrom, children } = newBlocklet;
|
|
2366
2435
|
const { did, version, name, title } = meta;
|
|
2367
2436
|
|
|
@@ -2426,11 +2495,11 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2426
2495
|
|
|
2427
2496
|
const status =
|
|
2428
2497
|
oldBlocklet.status === BlockletStatus.installed ? BlockletStatus.installed : BlockletStatus.stopped;
|
|
2429
|
-
await states.blocklet.setBlockletStatus(did, status, {
|
|
2498
|
+
await states.blocklet.setBlockletStatus(did, status, { componentDids });
|
|
2430
2499
|
|
|
2431
2500
|
// start new process
|
|
2432
2501
|
if (oldBlocklet.status === BlockletStatus.running) {
|
|
2433
|
-
await this.start({ did }, context);
|
|
2502
|
+
await this.start({ did, componentDids }, context);
|
|
2434
2503
|
logger.info('started blocklet for upgrading', { did, version });
|
|
2435
2504
|
}
|
|
2436
2505
|
|
|
@@ -2461,6 +2530,11 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2461
2530
|
|
|
2462
2531
|
await this._rollbackCache.remove({ did: blocklet.meta.did });
|
|
2463
2532
|
|
|
2533
|
+
this.emit(BlockletInternalEvents.componentsUpdated, {
|
|
2534
|
+
appDid: blocklet.appDid,
|
|
2535
|
+
components: getComponentsInternalInfo(blocklet),
|
|
2536
|
+
});
|
|
2537
|
+
|
|
2464
2538
|
return blocklet;
|
|
2465
2539
|
} catch (err) {
|
|
2466
2540
|
const b = await this._rollback('upgrade', did, oldBlocklet);
|
|
@@ -2517,10 +2591,12 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2517
2591
|
...context,
|
|
2518
2592
|
preDownload: async ({ downloadComponentIds }) => {
|
|
2519
2593
|
// update children status
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2594
|
+
if (downloadComponentIds?.length) {
|
|
2595
|
+
const blocklet1 = await states.blocklet.setBlockletStatus(did, BlockletStatus.downloading, {
|
|
2596
|
+
componentDids: downloadComponentIds,
|
|
2597
|
+
});
|
|
2598
|
+
this.emit(BlockletEvents.statusChange, blocklet1);
|
|
2599
|
+
}
|
|
2524
2600
|
},
|
|
2525
2601
|
onProgress: async (data) => {
|
|
2526
2602
|
this.emit(BlockletEvents.downloadBundleProgress, { appDid: appDid || did, meta: { did }, ...data });
|
|
@@ -2534,16 +2610,17 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2534
2610
|
});
|
|
2535
2611
|
}
|
|
2536
2612
|
|
|
2537
|
-
async _syncPm2Status(pm2Status, did) {
|
|
2613
|
+
async _syncPm2Status(pm2Status, did, componentDid) {
|
|
2538
2614
|
try {
|
|
2539
|
-
const
|
|
2540
|
-
|
|
2615
|
+
const blocklet = await states.blocklet.getBlocklet(did);
|
|
2616
|
+
const component = findComponentByIdV2(blocklet, componentDid);
|
|
2617
|
+
if (component && util.shouldUpdateBlockletStatus(component.status)) {
|
|
2541
2618
|
const newStatus = pm2StatusMap[pm2Status];
|
|
2542
|
-
await states.blocklet.setBlockletStatus(did, newStatus);
|
|
2543
|
-
logger.info('sync pm2 status to blocklet', { did, pm2Status, newStatus });
|
|
2619
|
+
await states.blocklet.setBlockletStatus(did, newStatus, { componentDids: [componentDid] });
|
|
2620
|
+
logger.info('sync pm2 status to blocklet', { did, componentDid, pm2Status, newStatus });
|
|
2544
2621
|
}
|
|
2545
2622
|
} catch (error) {
|
|
2546
|
-
logger.error('sync pm2 status to blocklet failed', { did, pm2Status, error });
|
|
2623
|
+
logger.error('sync pm2 status to blocklet failed', { did, componentDid, pm2Status, error });
|
|
2547
2624
|
}
|
|
2548
2625
|
}
|
|
2549
2626
|
|