@blocklet/sdk 1.17.0-beta-20251101-021648-3f521a7e → 1.17.0-beta-20251104-112713-e947b159
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/component/index.js +33 -22
- package/lib/config.d.ts +9 -1
- package/lib/config.js +58 -4
- package/lib/middlewares/auth.d.ts +1 -1
- package/lib/middlewares/auth.js +2 -1
- package/lib/middlewares/session.d.ts +1 -1
- package/lib/middlewares/session.js +2 -1
- package/lib/middlewares/user.d.ts +1 -1
- package/lib/middlewares/user.js +2 -1
- package/lib/service/notification.d.ts +1 -0
- package/lib/service/notification.js +64 -3
- package/lib/wallet.js +2 -2
- package/package.json +18 -18
package/lib/component/index.js
CHANGED
|
@@ -50,12 +50,34 @@ const Util = __importStar(require("./util"));
|
|
|
50
50
|
const component_api_1 = __importDefault(require("../util/component-api"));
|
|
51
51
|
const parse_docker_endpoint_1 = require("../util/parse-docker-endpoint");
|
|
52
52
|
const debug = (0, debug_1.default)('@blocklet/sdk:component');
|
|
53
|
+
const getComponent = (name) => {
|
|
54
|
+
const item = (0, config_1.getComponents)().find((x) => [x.title, x.name, x.did].includes(name));
|
|
55
|
+
return item;
|
|
56
|
+
};
|
|
57
|
+
const getComponentWebEndpoint = (keyword) => {
|
|
58
|
+
const item = getComponent(keyword);
|
|
59
|
+
const endpoint = item ? item.webEndpoint : '';
|
|
60
|
+
return (0, parse_docker_endpoint_1.parseDockerComponentEndpoint)(endpoint, item);
|
|
61
|
+
};
|
|
62
|
+
exports.getComponentWebEndpoint = getComponentWebEndpoint;
|
|
53
63
|
// eslint-disable-next-line require-await
|
|
54
|
-
const doCall =
|
|
64
|
+
const doCall = ({ url, componentName, callPath, headers = {}, ...options }, retryOptions = {}) => (0, p_retry_1.default)(async () => {
|
|
55
65
|
const startTime = Date.now();
|
|
66
|
+
let realUrl = url;
|
|
67
|
+
if (componentName && callPath) {
|
|
68
|
+
const component = getComponent(componentName);
|
|
69
|
+
if (!component) {
|
|
70
|
+
throw new Error(`can not find component ${componentName}`);
|
|
71
|
+
}
|
|
72
|
+
const baseURL = (0, parse_docker_endpoint_1.parseDockerComponentEndpoint)(component.webEndpoint, component);
|
|
73
|
+
if (!baseURL) {
|
|
74
|
+
throw new Error(`can not find web endpoint for ${componentName}`);
|
|
75
|
+
}
|
|
76
|
+
realUrl = (0, ufo_1.joinURL)(baseURL, callPath);
|
|
77
|
+
}
|
|
56
78
|
try {
|
|
57
79
|
const res = await (0, component_api_1.default)({
|
|
58
|
-
url,
|
|
80
|
+
url: realUrl,
|
|
59
81
|
timeout: 60 * 1000,
|
|
60
82
|
...options,
|
|
61
83
|
headers,
|
|
@@ -76,6 +98,13 @@ const doCall = async ({ url, headers = {}, ...options }, retryOptions = {}) => (
|
|
|
76
98
|
if (error.response && error.response.status < 500 && error.response.status >= 400) {
|
|
77
99
|
throw new p_retry_1.default.AbortError(error);
|
|
78
100
|
}
|
|
101
|
+
// Do not retry if getaddrinfo ENOTFOUND
|
|
102
|
+
if (error.message &&
|
|
103
|
+
(error.message.includes('getaddrinfo ENOTFOUND') || error.message.includes('timeout of'))) {
|
|
104
|
+
// 如果加载时间超过 maxTime,则缩短下次加载时间到 maxTime
|
|
105
|
+
(0, config_1.reduceNextLoadTime)(1000);
|
|
106
|
+
throw new p_retry_1.default.AbortError(error);
|
|
107
|
+
}
|
|
79
108
|
throw error;
|
|
80
109
|
}
|
|
81
110
|
}, {
|
|
@@ -86,34 +115,16 @@ const doCall = async ({ url, headers = {}, ...options }, retryOptions = {}) => (
|
|
|
86
115
|
maxTimeout: retryOptions.maxTimeout || 5000,
|
|
87
116
|
onFailedAttempt: retryOptions.onFailedAttempt || noop_1.default,
|
|
88
117
|
});
|
|
89
|
-
const getComponent = (name) => {
|
|
90
|
-
const item = (0, config_1.getComponents)().find((x) => [x.title, x.name, x.did].includes(name));
|
|
91
|
-
return item;
|
|
92
|
-
};
|
|
93
|
-
const getComponentWebEndpoint = (keyword) => {
|
|
94
|
-
const item = getComponent(keyword);
|
|
95
|
-
const endpoint = item ? item.webEndpoint : '';
|
|
96
|
-
return (0, parse_docker_endpoint_1.parseDockerComponentEndpoint)(endpoint, item);
|
|
97
|
-
};
|
|
98
|
-
exports.getComponentWebEndpoint = getComponentWebEndpoint;
|
|
99
118
|
const call = async ({ name, method = 'POST', path: _path, ...options }, retryOptions = {}) => {
|
|
100
119
|
if (!name) {
|
|
101
120
|
throw new Error('component.call: name is required');
|
|
102
121
|
}
|
|
103
|
-
const component = getComponent(name);
|
|
104
|
-
if (!component) {
|
|
105
|
-
throw new Error(`can not find component ${name}`);
|
|
106
|
-
}
|
|
107
|
-
const baseURL = (0, parse_docker_endpoint_1.parseDockerComponentEndpoint)(component.webEndpoint, component);
|
|
108
|
-
if (!baseURL) {
|
|
109
|
-
throw new Error(`can not find web endpoint for ${name}`);
|
|
110
|
-
}
|
|
111
|
-
const url = (0, ufo_1.joinURL)(baseURL, _path);
|
|
112
122
|
try {
|
|
113
|
-
const resp = await doCall({ url, method, ...options }, retryOptions);
|
|
123
|
+
const resp = await doCall({ url: '', componentName: name, callPath: _path, method, ...options }, retryOptions);
|
|
114
124
|
return resp;
|
|
115
125
|
}
|
|
116
126
|
catch (error) {
|
|
127
|
+
const component = getComponent(name);
|
|
117
128
|
if (component.status !== constant_1.BlockletStatus.running) {
|
|
118
129
|
throw new Error(`component ${name} is not running`);
|
|
119
130
|
}
|
package/lib/config.d.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { EventEmitter } from 'events';
|
|
2
2
|
import { TComponentInternalInfo } from '@blocklet/meta/lib/blocklet';
|
|
3
3
|
declare const events: EventEmitter<[never]>;
|
|
4
|
+
declare const configSettings: {
|
|
5
|
+
loadFileTimeout: number;
|
|
6
|
+
};
|
|
4
7
|
declare const Events: {
|
|
5
8
|
componentAdded: string;
|
|
6
9
|
componentUpdated: string;
|
|
@@ -60,6 +63,7 @@ type MountPoint = TComponentInternalInfo & {
|
|
|
60
63
|
type TComponent = MountPoint;
|
|
61
64
|
type TComponents = Array<TComponent>;
|
|
62
65
|
declare const componentStore: TComponents;
|
|
66
|
+
declare const reduceNextLoadTime: (maxTime: number) => void;
|
|
63
67
|
declare const getComponents: () => TComponents;
|
|
64
68
|
declare const _handleComponentUpdateOld: (data: {
|
|
65
69
|
components: TComponents;
|
|
@@ -93,7 +97,7 @@ declare const getBlockletSettings: () => {
|
|
|
93
97
|
};
|
|
94
98
|
declare const getBlockletJs: (pageGroup?: string, pathPrefix?: string, source?: string) => string;
|
|
95
99
|
export { logger, setLogger, env, componentStore as components, getComponents, MountPoint, // @deprecated, for backward compatibility
|
|
96
|
-
TComponent, events, Events, getBlockletJs, _handleComponentUpdateOld, _handleAppConfigUpdate, _handleAppSettingUpdate, _handleComponentInstalled, _handleComponentUpdated, _handleComponentStarted, _handleComponentStopped, _handleComponentRemoved, _handleComponentConfigUpdate, getBlockletSettings, };
|
|
100
|
+
TComponent, events, Events, getBlockletJs, _handleComponentUpdateOld, _handleAppConfigUpdate, _handleAppSettingUpdate, _handleComponentInstalled, _handleComponentUpdated, _handleComponentStarted, _handleComponentStopped, _handleComponentRemoved, _handleComponentConfigUpdate, reduceNextLoadTime, getBlockletSettings, configSettings, };
|
|
97
101
|
declare const _default: {
|
|
98
102
|
logger: {
|
|
99
103
|
info: {
|
|
@@ -162,5 +166,9 @@ declare const _default: {
|
|
|
162
166
|
federated: any;
|
|
163
167
|
enableBlacklist: boolean;
|
|
164
168
|
};
|
|
169
|
+
reduceNextLoadTime: (maxTime: number) => void;
|
|
170
|
+
configSettings: {
|
|
171
|
+
loadFileTimeout: number;
|
|
172
|
+
};
|
|
165
173
|
};
|
|
166
174
|
export default _default;
|
package/lib/config.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.getBlockletSettings = exports._handleComponentConfigUpdate = exports._handleComponentRemoved = exports._handleComponentStopped = exports._handleComponentStarted = exports._handleComponentUpdated = exports._handleComponentInstalled = exports._handleAppSettingUpdate = exports._handleAppConfigUpdate = exports._handleComponentUpdateOld = exports.getBlockletJs = exports.Events = exports.events = exports.getComponents = exports.components = exports.env = exports.setLogger = exports.logger = void 0;
|
|
6
|
+
exports.configSettings = exports.getBlockletSettings = exports.reduceNextLoadTime = exports._handleComponentConfigUpdate = exports._handleComponentRemoved = exports._handleComponentStopped = exports._handleComponentStarted = exports._handleComponentUpdated = exports._handleComponentInstalled = exports._handleAppSettingUpdate = exports._handleAppConfigUpdate = exports._handleComponentUpdateOld = exports.getBlockletJs = exports.Events = exports.events = exports.getComponents = exports.components = exports.env = exports.setLogger = exports.logger = void 0;
|
|
7
7
|
/* eslint-disable prettier/prettier */
|
|
8
8
|
/* eslint-disable no-console */
|
|
9
9
|
const path_1 = __importDefault(require("path"));
|
|
@@ -29,6 +29,10 @@ const blocklet_1 = require("./service/blocklet");
|
|
|
29
29
|
const debug = (0, debug_1.default)('@blocklet/sdk:config');
|
|
30
30
|
const events = new events_1.EventEmitter();
|
|
31
31
|
exports.events = events;
|
|
32
|
+
const configSettings = {
|
|
33
|
+
loadFileTimeout: 120000,
|
|
34
|
+
};
|
|
35
|
+
exports.configSettings = configSettings;
|
|
32
36
|
let blockletClient;
|
|
33
37
|
const Events = {
|
|
34
38
|
componentAdded: 'componentAdded',
|
|
@@ -73,9 +77,10 @@ const appDataDir = process.env.BLOCKLET_APP_DATA_DIR;
|
|
|
73
77
|
let appEnvFromDisk = {};
|
|
74
78
|
let envFromDisk = {};
|
|
75
79
|
let componentsFromDisk;
|
|
80
|
+
let configFile;
|
|
76
81
|
if (appDataDir) {
|
|
77
82
|
try {
|
|
78
|
-
|
|
83
|
+
configFile = path_1.default.join(appDataDir, constant_1.APP_CONFIG_FILE_PATH);
|
|
79
84
|
if (fs_1.default.existsSync(configFile)) {
|
|
80
85
|
let configRaw = fs_1.default.readFileSync(configFile).toString();
|
|
81
86
|
if (process.env.DOCKER_HOST_SERVER_DIR && process.env.DOCKER_CONTAINER_SERVER_DIR) {
|
|
@@ -134,7 +139,53 @@ const initComponentStore = () => {
|
|
|
134
139
|
};
|
|
135
140
|
const componentStore = initComponentStore();
|
|
136
141
|
exports.components = componentStore;
|
|
137
|
-
|
|
142
|
+
let lastLoadTime = 0;
|
|
143
|
+
// 缩短下次加载时间到 maxTime, 如果已经快到时间了, 不变更
|
|
144
|
+
const reduceNextLoadTime = (maxTime) => {
|
|
145
|
+
if (typeof maxTime !== 'number' || maxTime < 0) {
|
|
146
|
+
throw new Error('maxTime must be a positive number');
|
|
147
|
+
}
|
|
148
|
+
const now = Date.now();
|
|
149
|
+
// 计算自上次加载以来经过的时间
|
|
150
|
+
const elapsed = now - lastLoadTime;
|
|
151
|
+
const remaining = configSettings.loadFileTimeout - elapsed;
|
|
152
|
+
// 如果剩余时间已经比 maxTime 短,说明快要重新加载了,忽略
|
|
153
|
+
if (remaining <= maxTime)
|
|
154
|
+
return;
|
|
155
|
+
// 根据最新的 maxTime 调整 lastLoadTime,使得下次加载提前触发
|
|
156
|
+
lastLoadTime = now - (configSettings.loadFileTimeout - maxTime);
|
|
157
|
+
};
|
|
158
|
+
exports.reduceNextLoadTime = reduceNextLoadTime;
|
|
159
|
+
const getComponents = () => {
|
|
160
|
+
const now = Date.now();
|
|
161
|
+
if (now - lastLoadTime < configSettings.loadFileTimeout) {
|
|
162
|
+
return componentStore;
|
|
163
|
+
}
|
|
164
|
+
lastLoadTime = now;
|
|
165
|
+
try {
|
|
166
|
+
if (configFile && fs_1.default.existsSync(configFile)) {
|
|
167
|
+
let configRaw = fs_1.default.readFileSync(configFile).toString();
|
|
168
|
+
if (process.env.DOCKER_HOST_SERVER_DIR && process.env.DOCKER_CONTAINER_SERVER_DIR) {
|
|
169
|
+
configRaw = configRaw.replace(new RegExp(process.env.DOCKER_HOST_SERVER_DIR, 'g'), process.env.DOCKER_CONTAINER_SERVER_DIR);
|
|
170
|
+
}
|
|
171
|
+
const config = JSON.parse(configRaw);
|
|
172
|
+
componentsFromDisk = config.components;
|
|
173
|
+
const componentsMap = {};
|
|
174
|
+
for (const component of componentsFromDisk) {
|
|
175
|
+
componentsMap[component.did] = component;
|
|
176
|
+
}
|
|
177
|
+
componentStore.length = 0;
|
|
178
|
+
for (const component of componentsFromDisk) {
|
|
179
|
+
componentStore.push(component);
|
|
180
|
+
}
|
|
181
|
+
_fillWebEndpoint(componentStore);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
catch (error) {
|
|
185
|
+
logger.error(error);
|
|
186
|
+
}
|
|
187
|
+
return componentStore;
|
|
188
|
+
};
|
|
138
189
|
exports.getComponents = getComponents;
|
|
139
190
|
const updateComponentStoreInDocker = (components) => {
|
|
140
191
|
if (!components || !components.length) {
|
|
@@ -413,12 +464,15 @@ exports.default = {
|
|
|
413
464
|
setLogger,
|
|
414
465
|
env,
|
|
415
466
|
getComponents,
|
|
467
|
+
// @deprecated, no safe, please use getComponents
|
|
416
468
|
get components() {
|
|
417
|
-
return
|
|
469
|
+
return getComponents();
|
|
418
470
|
},
|
|
419
471
|
events,
|
|
420
472
|
Events,
|
|
421
473
|
fetchBlockletJs,
|
|
422
474
|
getBlockletJs,
|
|
423
475
|
getBlockletSettings,
|
|
476
|
+
reduceNextLoadTime,
|
|
477
|
+
configSettings,
|
|
424
478
|
};
|
package/lib/middlewares/auth.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.authMiddleware = void 0;
|
|
3
|
+
exports.auth = exports.authMiddleware = void 0;
|
|
4
4
|
const lru_cache_1 = require("lru-cache");
|
|
5
5
|
const blocklet_1 = require("../service/blocklet");
|
|
6
6
|
const login_1 = require("../util/login");
|
|
@@ -75,4 +75,5 @@ const authMiddleware = ({ roles, permissions, kyc, methods, getClient = getServi
|
|
|
75
75
|
};
|
|
76
76
|
};
|
|
77
77
|
exports.authMiddleware = authMiddleware;
|
|
78
|
+
exports.auth = authMiddleware;
|
|
78
79
|
authMiddleware.getServiceClient = getServiceClient;
|
|
@@ -11,4 +11,4 @@ type SessionOptions = {
|
|
|
11
11
|
declare const sessionMiddleware: (options?: SessionOptions) => (req: Request & {
|
|
12
12
|
user?: SessionUser;
|
|
13
13
|
}, res: Response, next: NextFunction) => Promise<void>;
|
|
14
|
-
export { sessionMiddleware };
|
|
14
|
+
export { sessionMiddleware, sessionMiddleware as session };
|
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.sessionMiddleware = void 0;
|
|
6
|
+
exports.session = exports.sessionMiddleware = void 0;
|
|
7
7
|
const get_token_from_req_1 = require("@abtnode/util/lib/get-token-from-req");
|
|
8
8
|
const service_api_1 = __importDefault(require("../util/service-api"));
|
|
9
9
|
const login_1 = require("../util/login");
|
|
@@ -73,3 +73,4 @@ const sessionMiddleware = (options = {}) => {
|
|
|
73
73
|
};
|
|
74
74
|
};
|
|
75
75
|
exports.sessionMiddleware = sessionMiddleware;
|
|
76
|
+
exports.session = sessionMiddleware;
|
package/lib/middlewares/user.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.userMiddleware = void 0;
|
|
3
|
+
exports.user = exports.userMiddleware = void 0;
|
|
4
4
|
const util_1 = require("util");
|
|
5
5
|
const login_1 = require("../util/login");
|
|
6
6
|
const userMiddleware = (0, util_1.deprecate)(() => (req, res, next) => {
|
|
@@ -17,3 +17,4 @@ const userMiddleware = (0, util_1.deprecate)(() => (req, res, next) => {
|
|
|
17
17
|
next();
|
|
18
18
|
}, 'user middleware is deprecated, please use session middleware for better security');
|
|
19
19
|
exports.userMiddleware = userMiddleware;
|
|
20
|
+
exports.user = userMiddleware;
|
|
@@ -31,6 +31,7 @@ export declare const broadcast: (notification: TNotificationInput, options?: TSe
|
|
|
31
31
|
export declare const _eventBus: EventEmitter<[never]>;
|
|
32
32
|
export declare const _emitter: EventEmitter<[never]>;
|
|
33
33
|
export declare const ensureClient: () => Promise<void>;
|
|
34
|
+
export declare const cleanup: () => void;
|
|
34
35
|
export declare const on: (event: string, cb?: $TSFixMe) => Promise<EventEmitter<[never]>>;
|
|
35
36
|
export declare const off: any;
|
|
36
37
|
export declare const _message: {
|
|
@@ -36,7 +36,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
36
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.sendToRelay = exports.sendToMail = exports.sendToUser = exports._message = exports.off = exports.on = exports.ensureClient = exports._emitter = exports._eventBus = exports.broadcast = exports.getSender = void 0;
|
|
39
|
+
exports.sendToRelay = exports.sendToMail = exports.sendToUser = exports._message = exports.off = exports.on = exports.cleanup = exports.ensureClient = exports._emitter = exports._eventBus = exports.broadcast = exports.getSender = void 0;
|
|
40
|
+
/* eslint-disable no-console */
|
|
40
41
|
/* eslint-disable @typescript-eslint/naming-convention */
|
|
41
42
|
const Jwt = __importStar(require("@arcblock/jwt"));
|
|
42
43
|
const debug_1 = __importDefault(require("debug"));
|
|
@@ -111,8 +112,11 @@ const broadcast = async (notification, options = {}) => {
|
|
|
111
112
|
exports.broadcast = broadcast;
|
|
112
113
|
const noop = () => { };
|
|
113
114
|
const emitter = new node_events_1.EventEmitter();
|
|
115
|
+
emitter.setMaxListeners(0);
|
|
114
116
|
const messageEmitter = new node_events_1.EventEmitter();
|
|
117
|
+
messageEmitter.setMaxListeners(0);
|
|
115
118
|
exports._eventBus = new node_events_1.EventEmitter(); // for event bus
|
|
119
|
+
exports._eventBus.setMaxListeners(0);
|
|
116
120
|
exports._emitter = emitter; // export internal emitter for testing
|
|
117
121
|
const emitError = (error) => {
|
|
118
122
|
messageEmitter.emit('error', error);
|
|
@@ -123,12 +127,48 @@ const ensureErrorListener = () => {
|
|
|
123
127
|
messageEmitter.on('error', noop);
|
|
124
128
|
exports._eventBus.on('error', noop);
|
|
125
129
|
};
|
|
130
|
+
let client = null;
|
|
131
|
+
let reconnectTimer = null;
|
|
132
|
+
let reconnectAttempts = 0;
|
|
133
|
+
const MAX_RECONNECT_ATTEMPTS = process.env.NODE_ENV === 'test' ? 5 : 30;
|
|
134
|
+
const RECONNECT_DELAY_MS = process.env.NODE_ENV === 'test' ? 500 : 2000;
|
|
135
|
+
const reconnect = () => {
|
|
136
|
+
// Schedule reconnection (only once even if multiple channels fail)
|
|
137
|
+
if (!reconnectTimer) {
|
|
138
|
+
// Check retry limit
|
|
139
|
+
if (reconnectAttempts >= MAX_RECONNECT_ATTEMPTS) {
|
|
140
|
+
console.error(`Max reconnection attempts (${MAX_RECONNECT_ATTEMPTS}) reached. Stopping reconnection.`);
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
reconnectAttempts += 1;
|
|
144
|
+
console.log(`Scheduling reconnection attempt ${reconnectAttempts}/${MAX_RECONNECT_ATTEMPTS}...`);
|
|
145
|
+
reconnectTimer = setTimeout(async () => {
|
|
146
|
+
reconnectTimer = null;
|
|
147
|
+
// eslint-disable-next-line no-use-before-define, @typescript-eslint/no-use-before-define
|
|
148
|
+
await initClient();
|
|
149
|
+
}, RECONNECT_DELAY_MS);
|
|
150
|
+
}
|
|
151
|
+
};
|
|
126
152
|
const joinChannelErrorHandler = (name, type, emitters) => (err) => {
|
|
127
153
|
const msg = `join ${name || 'channel'} ${type || 'error'}${err?.message ? ': ' : ''}${err?.message || ''}`;
|
|
128
154
|
console.error(msg);
|
|
129
155
|
(emitters || [emitter]).forEach((x) => x.emit('error', { message: msg }));
|
|
156
|
+
// On any join error/timeout, cleanup client and schedule reconnect with fresh token
|
|
157
|
+
if (client) {
|
|
158
|
+
console.log(`Cleaning up client due to ${name} join error, will reconnect with fresh token...`);
|
|
159
|
+
try {
|
|
160
|
+
client.disconnect();
|
|
161
|
+
}
|
|
162
|
+
catch (e) {
|
|
163
|
+
console.error('Error disconnecting client:', e);
|
|
164
|
+
}
|
|
165
|
+
client = null;
|
|
166
|
+
reconnect();
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
const joinSuccessHandler = () => {
|
|
170
|
+
reconnectAttempts = 0;
|
|
130
171
|
};
|
|
131
|
-
let client = null;
|
|
132
172
|
const initClient = async () => {
|
|
133
173
|
if (!client) {
|
|
134
174
|
ensureErrorListener();
|
|
@@ -155,18 +195,22 @@ const initClient = async () => {
|
|
|
155
195
|
const eventBusChannel = client.channel((0, channel_1.getEventBusChannel)(appDid), () => ({ token, pk }));
|
|
156
196
|
messageChannel
|
|
157
197
|
.join()
|
|
198
|
+
.receive('ok', joinSuccessHandler)
|
|
158
199
|
.receive('error', joinChannelErrorHandler('message channel', 'error', [messageEmitter, emitter]))
|
|
159
200
|
.receive('timeout', joinChannelErrorHandler('message channel', 'timeout', [messageEmitter, emitter]));
|
|
160
201
|
appPublicChannel
|
|
161
202
|
.join()
|
|
203
|
+
.receive('ok', joinSuccessHandler)
|
|
162
204
|
.receive('error', joinChannelErrorHandler('app public channel', 'error'))
|
|
163
205
|
.receive('timeout', joinChannelErrorHandler('app public channel', 'timeout'));
|
|
164
206
|
componentChannel
|
|
165
207
|
.join()
|
|
208
|
+
.receive('ok', joinSuccessHandler)
|
|
166
209
|
.receive('error', joinChannelErrorHandler('app component channel', 'error'))
|
|
167
210
|
.receive('timeout', joinChannelErrorHandler('app component channel', 'timeout'));
|
|
168
211
|
eventBusChannel
|
|
169
212
|
.join()
|
|
213
|
+
.receive('ok', joinSuccessHandler)
|
|
170
214
|
.receive('error', joinChannelErrorHandler('eventbus channel', 'error'))
|
|
171
215
|
.receive('timeout', joinChannelErrorHandler('eventbus channel', 'timeout'));
|
|
172
216
|
messageChannel.on('message', ({ status, response } = {}) => {
|
|
@@ -207,7 +251,12 @@ const initClient = async () => {
|
|
|
207
251
|
// verify sender is server
|
|
208
252
|
const tolerance = 600;
|
|
209
253
|
if (!(await Jwt.verify(sender.token, process.env.ABT_NODE_PK, { tolerance }))) {
|
|
210
|
-
const message = `verify sender failed in internal events. event: ${event}, sender: ${JSON.stringify(
|
|
254
|
+
const message = `verify sender failed in internal events. event: ${event}, sender: ${JSON.stringify({
|
|
255
|
+
sender,
|
|
256
|
+
decode: Jwt.decode(sender.token),
|
|
257
|
+
now: Date.now(),
|
|
258
|
+
ABT_NODE_PK: process.env.ABT_NODE_PK,
|
|
259
|
+
})}`;
|
|
211
260
|
emitError({ message });
|
|
212
261
|
console.error(message);
|
|
213
262
|
return;
|
|
@@ -250,6 +299,18 @@ const ensureClient = async () => {
|
|
|
250
299
|
}
|
|
251
300
|
};
|
|
252
301
|
exports.ensureClient = ensureClient;
|
|
302
|
+
const cleanup = () => {
|
|
303
|
+
if (reconnectTimer) {
|
|
304
|
+
clearTimeout(reconnectTimer);
|
|
305
|
+
reconnectTimer = null;
|
|
306
|
+
}
|
|
307
|
+
if (client) {
|
|
308
|
+
client.disconnect();
|
|
309
|
+
client = null;
|
|
310
|
+
}
|
|
311
|
+
reconnectAttempts = 0;
|
|
312
|
+
};
|
|
313
|
+
exports.cleanup = cleanup;
|
|
253
314
|
const on = async (event, cb) => {
|
|
254
315
|
await (0, exports.ensureClient)();
|
|
255
316
|
return emitter.on(event, cb);
|
package/lib/wallet.js
CHANGED
|
@@ -44,8 +44,8 @@ const createRemoteWallet = (publicKey, type, keyType = 'sk') => {
|
|
|
44
44
|
const baseWallet = (0, wallet_1.fromPublicKey)(publicKey, type);
|
|
45
45
|
const remoteWallet = Object.create(baseWallet);
|
|
46
46
|
// Add remote sign method
|
|
47
|
-
//
|
|
48
|
-
remoteWallet.sign = async (payload,
|
|
47
|
+
// Match the standard wallet.sign signature: sign(data, hashBeforeSign?, encoding?)
|
|
48
|
+
remoteWallet.sign = async (payload, hashBeforeSign, encoding) => {
|
|
49
49
|
try {
|
|
50
50
|
const { signature } = await (0, signature_1.remoteSign)(payload, { keyType, encoding, hashBeforeSign, type });
|
|
51
51
|
if (!signature) {
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "1.17.0-beta-
|
|
6
|
+
"version": "1.17.0-beta-20251104-112713-e947b159",
|
|
7
7
|
"description": "graphql client to read/write data on abt node",
|
|
8
8
|
"homepage": "https://www.arcblock.io/docs/blocklet-sdk-nodejs",
|
|
9
9
|
"main": "lib/index.js",
|
|
@@ -26,26 +26,26 @@
|
|
|
26
26
|
"author": "linchen1987 <linchen.1987@foxmail.com> (http://github.com/linchen1987)",
|
|
27
27
|
"license": "Apache-2.0",
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@abtnode/constant": "1.17.0-beta-
|
|
30
|
-
"@abtnode/db-cache": "1.17.0-beta-
|
|
31
|
-
"@abtnode/util": "1.17.0-beta-
|
|
32
|
-
"@arcblock/did": "^1.27.
|
|
33
|
-
"@arcblock/did-connect-js": "^1.27.
|
|
34
|
-
"@arcblock/did-ext": "^1.27.
|
|
35
|
-
"@arcblock/jwt": "^1.27.
|
|
36
|
-
"@arcblock/ws": "^1.27.
|
|
37
|
-
"@blocklet/constant": "1.17.0-beta-
|
|
38
|
-
"@blocklet/env": "1.17.0-beta-
|
|
39
|
-
"@blocklet/error": "^0.
|
|
40
|
-
"@blocklet/meta": "1.17.0-beta-
|
|
41
|
-
"@blocklet/server-js": "1.17.0-beta-
|
|
29
|
+
"@abtnode/constant": "1.17.0-beta-20251104-112713-e947b159",
|
|
30
|
+
"@abtnode/db-cache": "1.17.0-beta-20251104-112713-e947b159",
|
|
31
|
+
"@abtnode/util": "1.17.0-beta-20251104-112713-e947b159",
|
|
32
|
+
"@arcblock/did": "^1.27.1",
|
|
33
|
+
"@arcblock/did-connect-js": "^1.27.1",
|
|
34
|
+
"@arcblock/did-ext": "^1.27.1",
|
|
35
|
+
"@arcblock/jwt": "^1.27.1",
|
|
36
|
+
"@arcblock/ws": "^1.27.1",
|
|
37
|
+
"@blocklet/constant": "1.17.0-beta-20251104-112713-e947b159",
|
|
38
|
+
"@blocklet/env": "1.17.0-beta-20251104-112713-e947b159",
|
|
39
|
+
"@blocklet/error": "^0.3.0",
|
|
40
|
+
"@blocklet/meta": "1.17.0-beta-20251104-112713-e947b159",
|
|
41
|
+
"@blocklet/server-js": "1.17.0-beta-20251104-112713-e947b159",
|
|
42
42
|
"@blocklet/theme": "^3.1.54",
|
|
43
43
|
"@did-connect/authenticator": "^2.2.8",
|
|
44
44
|
"@did-connect/handler": "^2.2.8",
|
|
45
45
|
"@nedb/core": "^2.1.5",
|
|
46
|
-
"@ocap/mcrypto": "^1.27.
|
|
47
|
-
"@ocap/util": "^1.27.
|
|
48
|
-
"@ocap/wallet": "^1.27.
|
|
46
|
+
"@ocap/mcrypto": "^1.27.1",
|
|
47
|
+
"@ocap/util": "^1.27.1",
|
|
48
|
+
"@ocap/wallet": "^1.27.1",
|
|
49
49
|
"axios": "^1.7.9",
|
|
50
50
|
"cheerio": "1.0.0-rc.12",
|
|
51
51
|
"debug": "^4.4.1",
|
|
@@ -82,5 +82,5 @@
|
|
|
82
82
|
"ts-node": "^10.9.1",
|
|
83
83
|
"typescript": "^5.6.3"
|
|
84
84
|
},
|
|
85
|
-
"gitHead": "
|
|
85
|
+
"gitHead": "66c9180952f1dab415ff16b3ccd8eafd61baabf9"
|
|
86
86
|
}
|