@blocklet/did-space-js 1.0.43 → 1.0.44

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.
@@ -23,10 +23,22 @@ export declare abstract class IncrementalSyncBaseCommand<CommandInput extends In
23
23
  SYNC_AFTER: string;
24
24
  };
25
25
  private retryCount;
26
+ protected syncObjectRuntimeMap: Record<string, {
27
+ errorCount: number;
28
+ completedCount: number;
29
+ totalSize: number;
30
+ }>;
26
31
  constructor(input: CommandInput, context?: SpaceClientOptions);
27
32
  private initialize;
28
33
  abstract getLocalObjectsMap(): Promise<ObjectsMap>;
29
34
  abstract getRemoteObjectsMap(): Promise<ObjectsMap>;
35
+ /**
36
+ * @description 初始化同步对象运行时 map
37
+ * @param {SyncObject[]} syncObjects
38
+ * @return {*} {Promise<void>}
39
+ * @memberof IncrementalSyncBaseCommand
40
+ */
41
+ protected initializeSyncObjectRuntimeMap(syncObjects: SyncObject[]): void;
30
42
  /**
31
43
  *
32
44
  * @description 仅在开启调试模式时,输出调试信息,
@@ -76,5 +88,9 @@ export declare abstract class IncrementalSyncBaseCommand<CommandInput extends In
76
88
  * @memberof IncrementalSyncBaseCommand
77
89
  */
78
90
  protected shouldBeBackup(absolutePath: string): Promise<boolean>;
91
+ get errorCount(): number;
92
+ get completedCount(): number;
93
+ get totalSize(): number;
94
+ get totalCount(): number;
79
95
  destroy(): Promise<void>;
80
96
  }
@@ -40,6 +40,7 @@ class IncrementalSyncBaseCommand extends base_1.BaseCommand {
40
40
  SYNC_AFTER: 'sync.after',
41
41
  };
42
42
  retryCount = 0;
43
+ syncObjectRuntimeMap = {};
43
44
  constructor(input, context) {
44
45
  super(input, context);
45
46
  this.initialize(input);
@@ -72,6 +73,24 @@ class IncrementalSyncBaseCommand extends base_1.BaseCommand {
72
73
  (0, fs_extra_1.ensureDirSync)(this.input.tmpDir);
73
74
  }
74
75
  }
76
+ /**
77
+ * @description 初始化同步对象运行时 map
78
+ * @param {SyncObject[]} syncObjects
79
+ * @return {*} {Promise<void>}
80
+ * @memberof IncrementalSyncBaseCommand
81
+ */
82
+ initializeSyncObjectRuntimeMap(syncObjects) {
83
+ // 仅需要在首次进行初始化
84
+ if ((0, isEmpty_1.default)(this.syncObjectRuntimeMap)) {
85
+ syncObjects.forEach((x) => {
86
+ this.syncObjectRuntimeMap[x.key] = {
87
+ errorCount: 0,
88
+ completedCount: 0,
89
+ totalSize: 0,
90
+ };
91
+ });
92
+ }
93
+ }
75
94
  /**
76
95
  *
77
96
  * @description 仅在开启调试模式时,输出调试信息,
@@ -236,6 +255,18 @@ class IncrementalSyncBaseCommand extends base_1.BaseCommand {
236
255
  }
237
256
  return true;
238
257
  }
258
+ get errorCount() {
259
+ return Object.values(this.syncObjectRuntimeMap).reduce((acc, curr) => acc + curr.errorCount, 0);
260
+ }
261
+ get completedCount() {
262
+ return Object.values(this.syncObjectRuntimeMap).reduce((acc, curr) => acc + curr.completedCount, 0);
263
+ }
264
+ get totalSize() {
265
+ return Object.values(this.syncObjectRuntimeMap).reduce((acc, curr) => acc + curr.totalSize, 0);
266
+ }
267
+ get totalCount() {
268
+ return Object.keys(this.syncObjectRuntimeMap).length;
269
+ }
239
270
  async destroy() {
240
271
  this.queue.pause();
241
272
  this.queue.clear();
@@ -41,6 +41,7 @@ class IncrementalSyncPushCommand extends sync_base_1.IncrementalSyncBaseCommand
41
41
  const localObjectsMap = await this.getLocalObjectsMap();
42
42
  const remoteObjectsMap = await this.getRemoteObjectsMap();
43
43
  const syncObjects = await this.getWaitSyncObjects(localObjectsMap, remoteObjectsMap);
44
+ this.initializeSyncObjectRuntimeMap(syncObjects);
44
45
  debug(`[${(0, logger_1.now)()}] [waitUpload] waitUploadCount=${syncObjects.length}`);
45
46
  debug(`[${(0, logger_1.now)()}] [context]`, { input: this.input, context: (0, pick_1.default)(this.context, ['endpoint']) });
46
47
  return await this.sync(syncObjects);
@@ -124,18 +125,13 @@ class IncrementalSyncPushCommand extends sync_base_1.IncrementalSyncBaseCommand
124
125
  async sync(syncObjects) {
125
126
  this.queue.removeAllListeners();
126
127
  this.registerEvents();
127
- let errorCount = 0;
128
- let completedCount = 0;
129
- let totalSize = 0;
130
- const totalCount = syncObjects.length;
131
128
  // @ts-expect-error
132
129
  this.queue.on('error', async () => {
133
- errorCount += 1;
134
130
  await this.printDebugInfo({
135
131
  direction: 'push',
136
- completedCount,
137
- errorCount,
138
- totalCount,
132
+ completedCount: this.completedCount,
133
+ errorCount: this.errorCount,
134
+ totalCount: this.totalCount,
139
135
  });
140
136
  });
141
137
  const actions = syncObjects.map((x) => {
@@ -146,8 +142,8 @@ class IncrementalSyncPushCommand extends sync_base_1.IncrementalSyncBaseCommand
146
142
  const sourceKey = x.tempAbsolutePath;
147
143
  const targetKey = (0, path_1.join)(this.input.target, x.key);
148
144
  this.emit(sync_base_1.IncrementalSyncBaseCommand.EVENTS.SYNC_BEFORE, {
149
- completed: completedCount,
150
- total: totalCount,
145
+ completed: this.completedCount,
146
+ total: this.totalCount,
151
147
  key: x.key,
152
148
  });
153
149
  if (x.action === 'PUT' && !(await this.shouldBeBackup(sourceKey))) {
@@ -160,14 +156,14 @@ class IncrementalSyncPushCommand extends sync_base_1.IncrementalSyncBaseCommand
160
156
  // 开始上传
161
157
  debug(`[${(0, logger_1.now)()}] [sync:${x.action}.before] ${sourceKey} => ${targetKey} size=${(0, xbytes_1.default)(x.size, {
162
158
  iec: true,
163
- })} completed=${completedCount} total=${totalCount}`);
159
+ })} completed=${this.completedCount} total=${this.totalCount}`);
164
160
  if (x.action === 'PUT') {
165
161
  await new object_1.PutObjectCommand({
166
162
  key: targetKey,
167
163
  data: (0, fs_1.createReadStream)(sourceKey),
168
164
  hash: x.hash,
169
165
  }, this.context).request();
170
- totalSize += x.size;
166
+ this.syncObjectRuntimeMap[x.key].totalSize = x.size;
171
167
  }
172
168
  else {
173
169
  await new delete_object_1.DeleteObjectCommand({
@@ -175,22 +171,26 @@ class IncrementalSyncPushCommand extends sync_base_1.IncrementalSyncBaseCommand
175
171
  }, this.context).request();
176
172
  }
177
173
  // progress
178
- ++completedCount;
174
+ this.syncObjectRuntimeMap[x.key].completedCount = 1;
179
175
  this.printDebugInfo({
180
176
  direction: 'push',
181
- completedCount,
182
- errorCount,
183
- totalCount,
177
+ completedCount: this.completedCount,
178
+ errorCount: this.errorCount,
179
+ totalCount: this.totalCount,
184
180
  });
185
181
  this.emit(sync_base_1.IncrementalSyncBaseCommand.EVENTS.SYNC_AFTER, {
186
- completed: completedCount,
187
- total: totalCount,
182
+ completed: this.completedCount,
183
+ total: this.totalCount,
188
184
  key: x.key,
189
185
  });
190
186
  // 结束上传
191
187
  debug(`[${(0, logger_1.now)()}] [sync:${x.action}.after] ${sourceKey}=>${targetKey} size=${(0, xbytes_1.default)(x.size, {
192
188
  iec: true,
193
- })} completed=${completedCount} total=${totalCount}`);
189
+ })} completed=${this.completedCount} total=${this.totalCount}`);
190
+ }
191
+ catch (error) {
192
+ this.syncObjectRuntimeMap[x.key].errorCount = 1;
193
+ throw error;
194
194
  }
195
195
  finally {
196
196
  await this.destroyObject(x);
@@ -203,9 +203,9 @@ class IncrementalSyncPushCommand extends sync_base_1.IncrementalSyncBaseCommand
203
203
  statusCode: 200,
204
204
  data: {
205
205
  count: actions.length,
206
- errorCount,
206
+ errorCount: this.errorCount,
207
207
  duration: (Date.now() - this.startTime) / 1000,
208
- size: totalSize,
208
+ size: this.totalSize,
209
209
  },
210
210
  };
211
211
  }
@@ -125,7 +125,7 @@ class PutNftObjectCommand extends base_1.BaseCommand {
125
125
  ...formData.getHeaders(),
126
126
  },
127
127
  // @FIXME: @yejianchao 后续根据文件计算出一个合理的超时时间
128
- timeout: 5 * libs_1.MIN,
128
+ timeout: 5 * libs_1.TIMEOUT,
129
129
  };
130
130
  return config;
131
131
  }
@@ -39,9 +39,19 @@ export declare abstract class SyncFolderBaseCommand<CommandInput extends SyncFol
39
39
  * @description 保存待同步的对象,避免重复计算,可优化性能
40
40
  */
41
41
  protected waitSyncObjects: SyncObject[];
42
+ protected syncObjectRuntimeMap: Record<string, {
43
+ errorCount: number;
44
+ completedCount: number;
45
+ totalSize: number;
46
+ }>;
42
47
  constructor(input: CommandInput, context?: SpaceClientOptions);
43
48
  abstract getLocalObjectsMap(): Promise<ObjectsMap>;
44
49
  abstract getRemoteObjectsMap(): Promise<ObjectsMap>;
50
+ protected initializeSyncObjectRuntimeMap(syncObjects: SyncObject[]): void;
51
+ get errorCount(): number;
52
+ get completedCount(): number;
53
+ get totalSize(): number;
54
+ get totalCount(): number;
45
55
  /**
46
56
  *
47
57
  * @description 仅在开启调试模式时,输出调试信息,
@@ -50,6 +50,7 @@ class SyncFolderBaseCommand extends base_1.BaseCommand {
50
50
  * @description 保存待同步的对象,避免重复计算,可优化性能
51
51
  */
52
52
  waitSyncObjects = [];
53
+ syncObjectRuntimeMap = {};
53
54
  constructor(input, context) {
54
55
  super(input, context);
55
56
  if ((0, isUndefined_1.default)(input?.concurrency)) {
@@ -82,6 +83,25 @@ class SyncFolderBaseCommand extends base_1.BaseCommand {
82
83
  }
83
84
  this.queue = new p_queue_1.default({ concurrency: this.input.concurrency });
84
85
  }
86
+ initializeSyncObjectRuntimeMap(syncObjects) {
87
+ if ((0, isEmpty_1.default)(this.syncObjectRuntimeMap)) {
88
+ syncObjects.forEach((x) => {
89
+ this.syncObjectRuntimeMap[x.key] = { errorCount: 0, completedCount: 0, totalSize: 0 };
90
+ });
91
+ }
92
+ }
93
+ get errorCount() {
94
+ return Object.values(this.syncObjectRuntimeMap).reduce((acc, curr) => acc + curr.errorCount, 0);
95
+ }
96
+ get completedCount() {
97
+ return Object.values(this.syncObjectRuntimeMap).reduce((acc, curr) => acc + curr.completedCount, 0);
98
+ }
99
+ get totalSize() {
100
+ return Object.values(this.syncObjectRuntimeMap).reduce((acc, curr) => acc + curr.totalSize, 0);
101
+ }
102
+ get totalCount() {
103
+ return Object.keys(this.syncObjectRuntimeMap).length;
104
+ }
85
105
  /**
86
106
  *
87
107
  * @description 仅在开启调试模式时,输出调试信息,
@@ -13,6 +13,7 @@ const pick_1 = __importDefault(require("lodash/pick"));
13
13
  const filehound_1 = __importDefault(require("filehound"));
14
14
  const debug_1 = __importDefault(require("debug"));
15
15
  const xbytes_1 = __importDefault(require("xbytes"));
16
+ const lodash_1 = require("lodash");
16
17
  const get_object_1 = require("../object/get-object");
17
18
  const object_1 = require("../object");
18
19
  const libs_1 = require("../../libs");
@@ -35,6 +36,7 @@ class SyncFolderPullCommand extends sync_folder_base_1.SyncFolderBaseCommand {
35
36
  const remoteObjectsMap = await this.getRemoteObjectsMap();
36
37
  const localObjectsMap = await this.getLocalObjectsMap();
37
38
  const waitSyncObjects = await this.getWaitSyncObjects(remoteObjectsMap, localObjectsMap);
39
+ this.initializeSyncObjectRuntimeMap(waitSyncObjects);
38
40
  debug(`[${(0, logger_1.now)()}] [waitDownload]`, `waitDownloadCount=${waitSyncObjects.length}`);
39
41
  debug(`[${(0, logger_1.now)()}] [context]`, { input: this.input, context: (0, pick_1.default)(this.context, ['endpoint']) });
40
42
  return await this.sync(waitSyncObjects);
@@ -45,6 +47,9 @@ class SyncFolderPullCommand extends sync_folder_base_1.SyncFolderBaseCommand {
45
47
  }
46
48
  }
47
49
  async getRemoteObjectsMap() {
50
+ if (!(0, lodash_1.isEmpty)(this.remoteObjectsMap)) {
51
+ return this.remoteObjectsMap;
52
+ }
48
53
  let { data: objects } = await new object_1.ListObjectsCommand({ key: (0, path_1.join)(this.input.source) }, this.context).request();
49
54
  if ((0, isFunction_1.default)(this.input.filter)) {
50
55
  objects = objects.filter(this.input.filter);
@@ -53,6 +58,9 @@ class SyncFolderPullCommand extends sync_folder_base_1.SyncFolderBaseCommand {
53
58
  return map;
54
59
  }
55
60
  getLocalObjectsMap() {
61
+ if (!(0, lodash_1.isEmpty)(this.localObjectsMap)) {
62
+ return Promise.resolve(this.localObjectsMap);
63
+ }
56
64
  const files = filehound_1.default.create()
57
65
  .path(this.input.target)
58
66
  .includeFileStats()
@@ -76,18 +84,13 @@ class SyncFolderPullCommand extends sync_folder_base_1.SyncFolderBaseCommand {
76
84
  }
77
85
  async sync(syncObjects) {
78
86
  this.queue.removeAllListeners();
79
- let errorCount = 0;
80
- let completedCount = 0;
81
- let totalSize = 0;
82
- const totalCount = syncObjects.length;
83
87
  // @ts-expect-error
84
- this.queue.on('error', async () => {
85
- errorCount += 1;
86
- await this.printDebugInfo({
88
+ this.queue.on('error', () => {
89
+ this.printDebugInfo({
87
90
  direction: 'pull',
88
- completedCount,
89
- errorCount,
90
- totalCount,
91
+ completedCount: this.completedCount,
92
+ errorCount: this.errorCount,
93
+ totalCount: this.totalCount,
91
94
  });
92
95
  });
93
96
  const actions = syncObjects.map((x) => {
@@ -99,14 +102,14 @@ class SyncFolderPullCommand extends sync_folder_base_1.SyncFolderBaseCommand {
99
102
  const sourceKey = (0, path_1.join)(this.input.source, x.key);
100
103
  const targetKey = (0, path_1.join)(this.input.target, x.key);
101
104
  await this.triggerOnProgressHook({
102
- completed: completedCount,
103
- total: totalCount,
105
+ completed: this.completedCount,
106
+ total: this.totalCount,
104
107
  key: sourceKey,
105
108
  });
106
109
  // 开始下载
107
110
  debug(`[${(0, logger_1.now)()}] [sync:${x.action}.before] ${sourceKey} => ${targetKey} size=${(0, xbytes_1.default)(x.size, {
108
111
  iec: true,
109
- })} completed=${completedCount} total=${totalCount}`);
112
+ })} completed=${this.completedCount} total=${this.totalCount}`);
110
113
  const { data: stream, headers } = await new get_object_1.GetObjectCommand({
111
114
  key: sourceKey,
112
115
  }, this.context).request();
@@ -119,23 +122,23 @@ class SyncFolderPullCommand extends sync_folder_base_1.SyncFolderBaseCommand {
119
122
  await (0, libs_1.verifyObjectHash)(targetKey, headers['x-hash']);
120
123
  }
121
124
  // progress
122
- ++completedCount;
125
+ this.syncObjectRuntimeMap[x.key].completedCount = 1;
123
126
  await this.printDebugInfo({
124
127
  direction: 'pull',
125
- completedCount,
126
- errorCount,
127
- totalCount,
128
+ completedCount: this.completedCount,
129
+ errorCount: this.errorCount,
130
+ totalCount: this.totalCount,
128
131
  });
129
132
  await this.triggerOnAfterUploadHook({
130
- completed: completedCount,
131
- total: totalCount,
133
+ completed: this.completedCount,
134
+ total: this.totalCount,
132
135
  key: sourceKey,
133
136
  });
134
137
  // 下载完成
135
- totalSize += x.size;
138
+ this.syncObjectRuntimeMap[x.key].totalSize = x.size;
136
139
  debug(`[${(0, logger_1.now)()}] [sync:${x.action}.after] ${sourceKey} => ${targetKey} size=${(0, xbytes_1.default)(x.size, {
137
140
  iec: true,
138
- })} completed=${completedCount} total=${totalCount}`);
141
+ })} completed=${this.completedCount} total=${this.totalCount}`);
139
142
  };
140
143
  });
141
144
  await this.queue.addAll(actions);
@@ -143,10 +146,10 @@ class SyncFolderPullCommand extends sync_folder_base_1.SyncFolderBaseCommand {
143
146
  return {
144
147
  statusCode: 200,
145
148
  data: {
146
- errorCount,
149
+ errorCount: this.errorCount,
147
150
  count: actions.length,
148
151
  duration: (Date.now() - this.startTime) / 1000,
149
- size: totalSize,
152
+ size: this.totalSize,
150
153
  },
151
154
  };
152
155
  }
@@ -1,4 +1,4 @@
1
1
  import { type Got } from 'got';
2
- export declare const MIN: number;
2
+ export declare const TIMEOUT: number;
3
3
  export declare const api: import("axios").AxiosInstance;
4
4
  export declare const gotApi: Got;
package/dist/libs/api.js CHANGED
@@ -26,25 +26,25 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
26
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.gotApi = exports.api = exports.MIN = void 0;
29
+ exports.gotApi = exports.api = exports.TIMEOUT = void 0;
30
30
  const axios_1 = __importDefault(require("axios"));
31
31
  const agentkeepalive_1 = __importStar(require("agentkeepalive"));
32
32
  const got_1 = __importDefault(require("got"));
33
- exports.MIN = 60 * 1000;
33
+ exports.TIMEOUT = 1000 * 60 * 60 * 6;
34
34
  const httpAgent = new agentkeepalive_1.default({
35
35
  maxSockets: 64,
36
36
  maxFreeSockets: 16,
37
- timeout: exports.MIN,
38
- freeSocketTimeout: exports.MIN,
39
- keepAliveMsecs: exports.MIN,
37
+ timeout: exports.TIMEOUT,
38
+ freeSocketTimeout: exports.TIMEOUT,
39
+ keepAliveMsecs: exports.TIMEOUT,
40
40
  keepAlive: true,
41
41
  });
42
42
  const httpsAgent = new agentkeepalive_1.HttpsAgent({
43
43
  maxSockets: 64,
44
44
  maxFreeSockets: 16,
45
- timeout: exports.MIN,
46
- freeSocketTimeout: exports.MIN,
47
- keepAliveMsecs: exports.MIN,
45
+ timeout: exports.TIMEOUT,
46
+ freeSocketTimeout: exports.TIMEOUT,
47
+ keepAliveMsecs: exports.TIMEOUT,
48
48
  keepAlive: true,
49
49
  });
50
50
  exports.api = axios_1.default.create({
@@ -58,7 +58,7 @@ exports.gotApi = got_1.default.extend({
58
58
  http: httpAgent,
59
59
  https: httpsAgent,
60
60
  },
61
- timeout: 1000 * 60 * 60,
61
+ timeout: exports.TIMEOUT,
62
62
  retry: {
63
63
  limit: 3,
64
64
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blocklet/did-space-js",
3
- "version": "1.0.43",
3
+ "version": "1.0.44",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -33,7 +33,7 @@
33
33
  "@arcblock/jwt": "^1.19.19",
34
34
  "@arcblock/validator": "^1.19.19",
35
35
  "@blocklet/env": "^1.16.42-beta-20250408-072924-4b6a877a",
36
- "@did-space/core": "^1.0.43",
36
+ "@did-space/core": "^1.0.44",
37
37
  "@ocap/mcrypto": "^1.19.19",
38
38
  "@ocap/util": "^1.19.19",
39
39
  "@ocap/wallet": "^1.19.19",
@@ -77,5 +77,5 @@
77
77
  "ts-jest": "^28.0.8",
78
78
  "typescript": "^4.9.5"
79
79
  },
80
- "gitHead": "85a3f4751d5aec1b6b69d6f7e6e51e3282e5b390"
80
+ "gitHead": "5b4c87e2a4fbc3db28c6c95cd1799d1466844f53"
81
81
  }