@onekeyfe/hd-core 1.2.0-alpha.55 → 1.2.0-alpha.56
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/__tests__/device-state-contract.test.ts +1 -0
- package/__tests__/device-state-mapper.test.ts +1 -1
- package/__tests__/deviceSettings.test.ts +1 -1
- package/__tests__/protocol-v2.test.ts +4 -0
- package/__tests__/protocolV2FileWrite.test.ts +39 -0
- package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
- package/dist/api/helpers/protocolV2FileWrite.d.ts.map +1 -1
- package/dist/index.js +18 -3
- package/dist/protocols/protocol-v2/firmware.d.ts.map +1 -1
- package/dist/types/api/detectDeviceConnectProtocol.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/api/FirmwareUpdateV4.ts +15 -10
- package/src/api/helpers/protocolV2FileWrite.ts +16 -3
- package/src/protocols/protocol-v2/firmware.ts +2 -0
- package/src/types/api/detectDeviceConnectProtocol.ts +0 -1
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { EDeviceType } from '@onekeyfe/hd-shared';
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
|
+
PROTOCOL_V2_NEVER_TIMEOUT_MS,
|
|
4
5
|
getAutoLockOptions,
|
|
5
6
|
getAutoShutDownOptions,
|
|
6
7
|
getDeviceSettingsCapabilities,
|
|
7
8
|
getLanguageConfig,
|
|
8
9
|
mapLanguageFromProtocolV2,
|
|
9
10
|
mapLanguageToProtocolV2,
|
|
10
|
-
PROTOCOL_V2_NEVER_TIMEOUT_MS,
|
|
11
11
|
} from '../src/utils/deviceSettings';
|
|
12
12
|
|
|
13
13
|
describe('Pro 2 device settings options', () => {
|
|
@@ -6071,6 +6071,10 @@ describe('Protocol V2 firmware update targets', () => {
|
|
|
6071
6071
|
expect(writePayloads.map(payload => payload.file.offset)).toEqual([0, 1800]);
|
|
6072
6072
|
expect(writePayloads.map(payload => payload.file.data.byteLength)).toEqual([1800, 1]);
|
|
6073
6073
|
expect(writePayloads.map(payload => payload.ui_percentage)).toEqual([0, 100]);
|
|
6074
|
+
expect(typedCall.mock.calls.map(call => call[3])).toEqual([
|
|
6075
|
+
{ writeWithResponse: true },
|
|
6076
|
+
{ writeWithResponse: true },
|
|
6077
|
+
]);
|
|
6074
6078
|
});
|
|
6075
6079
|
|
|
6076
6080
|
test('ends device confirmation and starts install progress only after Protocol V2 ACK', async () => {
|
|
@@ -89,4 +89,43 @@ describe('writeProtocolV2File', () => {
|
|
|
89
89
|
expect(typedCall.mock.calls[1][2]).toEqual(typedCall.mock.calls[0][2]);
|
|
90
90
|
expect(onProgress).toHaveBeenCalledTimes(1);
|
|
91
91
|
});
|
|
92
|
+
|
|
93
|
+
test('按确认分片的时间窗口记录实时传输速率', async () => {
|
|
94
|
+
const data = new Uint8Array(4097);
|
|
95
|
+
const typedCall = jest.fn().mockResolvedValue({ message: {} });
|
|
96
|
+
const onProgress = jest.fn();
|
|
97
|
+
const dateNowSpy = jest
|
|
98
|
+
.spyOn(Date, 'now')
|
|
99
|
+
.mockReturnValueOnce(1_000)
|
|
100
|
+
.mockReturnValueOnce(2_000)
|
|
101
|
+
.mockReturnValueOnce(3_000);
|
|
102
|
+
|
|
103
|
+
try {
|
|
104
|
+
await writeProtocolV2File({
|
|
105
|
+
commands: { typedCall } as any,
|
|
106
|
+
path: 'vol1:/wallpapers/test.bin',
|
|
107
|
+
data,
|
|
108
|
+
onProgress,
|
|
109
|
+
});
|
|
110
|
+
} finally {
|
|
111
|
+
dateNowSpy.mockRestore();
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
expect(onProgress).toHaveBeenNthCalledWith(
|
|
115
|
+
1,
|
|
116
|
+
expect.objectContaining({
|
|
117
|
+
transferredBytes: 4000,
|
|
118
|
+
rateBytesPerSecond: 4000,
|
|
119
|
+
elapsedMs: 1000,
|
|
120
|
+
})
|
|
121
|
+
);
|
|
122
|
+
expect(onProgress).toHaveBeenNthCalledWith(
|
|
123
|
+
2,
|
|
124
|
+
expect.objectContaining({
|
|
125
|
+
transferredBytes: 4097,
|
|
126
|
+
rateBytesPerSecond: 97,
|
|
127
|
+
elapsedMs: 2000,
|
|
128
|
+
})
|
|
129
|
+
);
|
|
130
|
+
});
|
|
92
131
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FirmwareUpdateV4.d.ts","sourceRoot":"","sources":["../../src/api/FirmwareUpdateV4.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAC;AAkB/E,OAAO,KAAK,EAAE,sBAAsB,EAA0B,MAAM,6BAA6B,CAAC;AAmUlG,eAAO,MAAM,oCAAoC,WACvC,WAAW,GAAG,UAAU,eACnB,MAAM,GAAG,SAAS,YAKhC,CAAC;AAEF,eAAO,MAAM,iCAAiC,0BACrB,MAAM,uBACR,MAAM,SAa5B,CAAC;AAUF,MAAM,CAAC,OAAO,OAAO,gBAAiB,SAAQ,wBAAwB,CAAC,sBAAsB,CAAC;IAC5F,OAAO,CAAC,8BAA8B,CAAC,CAAS;IAEhD,qBAAqB;IAIrB,IAAI;IA6DJ,OAAO,CAAC,8BAA8B;IAiBhC,GAAG;;;;;YAKK,aAAa;YAwGb,2BAA2B;IAWzC,OAAO,CAAC,yBAAyB;IAKjC,OAAO,CAAC,kCAAkC;IAO1C,OAAO,CAAC,8BAA8B;YAMxB,iCAAiC;YAOjC,iCAAiC;YAOjC,iCAAiC;IAM/C,OAAO,CAAC,uBAAuB;IAI/B,OAAO,CAAC,4BAA4B;IASpC,OAAO,CAAC,2BAA2B;IAsBnC,OAAO,CAAC,yBAAyB;IAiBjC,OAAO,CAAC,wBAAwB;YAkBlB,iCAAiC;YAmCjC,+BAA+B;IAqD7C,OAAO,CAAC,qCAAqC;YAuB/B,8BAA8B;IAyB5C,OAAO,CAAC,wCAAwC;YAgBlC,gCAAgC;YAqChC,0BAA0B;YAe1B,6BAA6B;IAkC3C,OAAO,CAAC,0BAA0B;IAUlC,OAAO,CAAC,yBAAyB;IAU3B,6BAA6B;YA4BrB,+BAA+B;IAkD7C,OAAO,CAAC,6BAA6B;YAkCvB,uBAAuB;IA4GrC,OAAO,CAAC,mCAAmC;YAI7B,0BAA0B;IAaxC,OAAO,CAAC,4BAA4B;IAgEpC,OAAO,CAAC,6BAA6B;YAcvB,uCAAuC;YAoJvC,gCAAgC;YAchC,yBAAyB;YAQzB,8BAA8B;IAQ5C,OAAO,CAAC,0BAA0B;YAiBpB,qCAAqC;YAgDrC,yBAAyB;YA8DzB,8BAA8B;IAU5C,OAAO,CAAC,kCAAkC;YAI5B,6BAA6B;YAwB7B,wBAAwB;IAoDtC,OAAO,CAAC,sCAAsC;YAchC,cAAc;
|
|
1
|
+
{"version":3,"file":"FirmwareUpdateV4.d.ts","sourceRoot":"","sources":["../../src/api/FirmwareUpdateV4.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAC;AAkB/E,OAAO,KAAK,EAAE,sBAAsB,EAA0B,MAAM,6BAA6B,CAAC;AAmUlG,eAAO,MAAM,oCAAoC,WACvC,WAAW,GAAG,UAAU,eACnB,MAAM,GAAG,SAAS,YAKhC,CAAC;AAEF,eAAO,MAAM,iCAAiC,0BACrB,MAAM,uBACR,MAAM,SAa5B,CAAC;AAUF,MAAM,CAAC,OAAO,OAAO,gBAAiB,SAAQ,wBAAwB,CAAC,sBAAsB,CAAC;IAC5F,OAAO,CAAC,8BAA8B,CAAC,CAAS;IAEhD,qBAAqB;IAIrB,IAAI;IA6DJ,OAAO,CAAC,8BAA8B;IAiBhC,GAAG;;;;;YAKK,aAAa;YAwGb,2BAA2B;IAWzC,OAAO,CAAC,yBAAyB;IAKjC,OAAO,CAAC,kCAAkC;IAO1C,OAAO,CAAC,8BAA8B;YAMxB,iCAAiC;YAOjC,iCAAiC;YAOjC,iCAAiC;IAM/C,OAAO,CAAC,uBAAuB;IAI/B,OAAO,CAAC,4BAA4B;IASpC,OAAO,CAAC,2BAA2B;IAsBnC,OAAO,CAAC,yBAAyB;IAiBjC,OAAO,CAAC,wBAAwB;YAkBlB,iCAAiC;YAmCjC,+BAA+B;IAqD7C,OAAO,CAAC,qCAAqC;YAuB/B,8BAA8B;IAyB5C,OAAO,CAAC,wCAAwC;YAgBlC,gCAAgC;YAqChC,0BAA0B;YAe1B,6BAA6B;IAkC3C,OAAO,CAAC,0BAA0B;IAUlC,OAAO,CAAC,yBAAyB;IAU3B,6BAA6B;YA4BrB,+BAA+B;IAkD7C,OAAO,CAAC,6BAA6B;YAkCvB,uBAAuB;IA4GrC,OAAO,CAAC,mCAAmC;YAI7B,0BAA0B;IAaxC,OAAO,CAAC,4BAA4B;IAgEpC,OAAO,CAAC,6BAA6B;YAcvB,uCAAuC;YAoJvC,gCAAgC;YAchC,yBAAyB;YAQzB,8BAA8B;IAQ5C,OAAO,CAAC,0BAA0B;YAiBpB,qCAAqC;YAgDrC,yBAAyB;YA8DzB,8BAA8B;IAU5C,OAAO,CAAC,kCAAkC;YAI5B,6BAA6B;YAwB7B,wBAAwB;IAoDtC,OAAO,CAAC,sCAAsC;YAchC,cAAc;YAoCd,6BAA6B;YAW7B,0BAA0B;YAS1B,6BAA6B;YAmB7B,gBAAgB;IAiB9B,OAAO,CAAC,qBAAqB;CAM9B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocolV2FileWrite.d.ts","sourceRoot":"","sources":["../../../src/api/helpers/protocolV2FileWrite.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAElE,MAAM,MAAM,uBAAuB,GAAG,WAAW,GAAG,UAAU,GAAG,IAAI,GAAG,MAAM,CAAC;AAE/E,MAAM,MAAM,2BAA2B,GAAG;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACvC,QAAQ,EAAE,IAAI,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,uBAAuB,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,2BAA2B,KAAK,IAAI,CAAC;CAC9D,CAAC;
|
|
1
|
+
{"version":3,"file":"protocolV2FileWrite.d.ts","sourceRoot":"","sources":["../../../src/api/helpers/protocolV2FileWrite.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAElE,MAAM,MAAM,uBAAuB,GAAG,WAAW,GAAG,UAAU,GAAG,IAAI,GAAG,MAAM,CAAC;AAE/E,MAAM,MAAM,2BAA2B,GAAG;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACvC,QAAQ,EAAE,IAAI,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,uBAAuB,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,2BAA2B,KAAK,IAAI,CAAC;CAC9D,CAAC;AAKF,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,WASzD;AA8CD,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,0BAA0B;;;;;;GA0H5E"}
|
package/dist/index.js
CHANGED
|
@@ -50485,7 +50485,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
50485
50485
|
overwrite,
|
|
50486
50486
|
append: false,
|
|
50487
50487
|
ui_percentage: progress !== null && progress !== void 0 ? progress : undefined,
|
|
50488
|
-
});
|
|
50488
|
+
}, { writeWithResponse: true });
|
|
50489
50489
|
if (writeRes.type !== 'FilesystemFile') {
|
|
50490
50490
|
if (writeRes.type === 'CallMethodError') {
|
|
50491
50491
|
if (((_a = writeRes.message.error) !== null && _a !== void 0 ? _a : '').indexOf(SESSION_ERROR) > -1) {
|
|
@@ -50655,6 +50655,7 @@ class DeviceGetOnboardingStatus extends BaseMethod {
|
|
|
50655
50655
|
}
|
|
50656
50656
|
|
|
50657
50657
|
const MIN_FILE_CHUNK_SIZE = 64;
|
|
50658
|
+
const FILE_TRANSFER_RATE_WINDOW_MS = 1000;
|
|
50658
50659
|
function isProtocolV2ResponseTimeout(error) {
|
|
50659
50660
|
var _a, _b;
|
|
50660
50661
|
if (!error || typeof error !== 'object')
|
|
@@ -50729,6 +50730,9 @@ function writeProtocolV2File(options) {
|
|
|
50729
50730
|
let chunks = 0;
|
|
50730
50731
|
let lastMessage;
|
|
50731
50732
|
const startTime = Date.now();
|
|
50733
|
+
let rateWindowStartedAt = startTime;
|
|
50734
|
+
let rateWindowStartedBytes = 0;
|
|
50735
|
+
let rateBytesPerSecond;
|
|
50732
50736
|
while (written < dataLength) {
|
|
50733
50737
|
(_c = options.throwIfAborted) === null || _c === void 0 ? void 0 : _c.call(options);
|
|
50734
50738
|
const chunk = data.slice(written, Math.min(written + chunkSize, dataLength));
|
|
@@ -50772,13 +50776,24 @@ function writeProtocolV2File(options) {
|
|
|
50772
50776
|
written =
|
|
50773
50777
|
rawProcessedByte === undefined ? written + chunk.byteLength : processedByte - startOffset;
|
|
50774
50778
|
chunks += 1;
|
|
50775
|
-
const
|
|
50779
|
+
const now = Date.now();
|
|
50780
|
+
const elapsedMs = now - startTime;
|
|
50776
50781
|
const transferredBytes = Math.min(written, dataLength);
|
|
50782
|
+
const rateWindowElapsedMs = now - rateWindowStartedAt;
|
|
50783
|
+
if (rateWindowElapsedMs >= FILE_TRANSFER_RATE_WINDOW_MS) {
|
|
50784
|
+
const rateWindowBytes = Math.max(transferredBytes - rateWindowStartedBytes, 0);
|
|
50785
|
+
rateBytesPerSecond = Math.round((rateWindowBytes / rateWindowElapsedMs) * 1000);
|
|
50786
|
+
rateWindowStartedAt = now;
|
|
50787
|
+
rateWindowStartedBytes = transferredBytes;
|
|
50788
|
+
}
|
|
50789
|
+
else if (rateBytesPerSecond === undefined && elapsedMs > 0) {
|
|
50790
|
+
rateBytesPerSecond = Math.round((transferredBytes / elapsedMs) * 1000);
|
|
50791
|
+
}
|
|
50777
50792
|
(_l = options.onProgress) === null || _l === void 0 ? void 0 : _l.call(options, {
|
|
50778
50793
|
progress: getConfirmedProgress(startOffset + written, totalSize, written, dataLength),
|
|
50779
50794
|
transferredBytes,
|
|
50780
50795
|
totalBytes: dataLength,
|
|
50781
|
-
rateBytesPerSecond
|
|
50796
|
+
rateBytesPerSecond,
|
|
50782
50797
|
elapsedMs,
|
|
50783
50798
|
});
|
|
50784
50799
|
if (options.paceMs && options.paceMs > 0) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"firmware.d.ts","sourceRoot":"","sources":["../../../src/protocols/protocol-v2/firmware.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,4BAA4B;;;;;;;;;;;;CAY/B,CAAC;
|
|
1
|
+
{"version":3,"file":"firmware.d.ts","sourceRoot":"","sources":["../../../src/protocols/protocol-v2/firmware.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,4BAA4B;;;;;;;;;;;;CAY/B,CAAC;AAIX,MAAM,MAAM,4BAA4B,GACtC,CAAC,OAAO,4BAA4B,CAAC,CAAC,MAAM,OAAO,4BAA4B,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"detectDeviceConnectProtocol.d.ts","sourceRoot":"","sources":["../../../src/types/api/detectDeviceConnectProtocol.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"detectDeviceConnectProtocol.d.ts","sourceRoot":"","sources":["../../../src/types/api/detectDeviceConnectProtocol.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAE1C,MAAM,CAAC,OAAO,UAAU,2BAA2B,CACjD,SAAS,EAAE,MAAM,GAChB,QAAQ,CAAC,uBAAuB,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onekeyfe/hd-core",
|
|
3
|
-
"version": "1.2.0-alpha.
|
|
3
|
+
"version": "1.2.0-alpha.56",
|
|
4
4
|
"description": "Core processes and APIs for communicating with OneKey hardware devices.",
|
|
5
5
|
"author": "OneKey",
|
|
6
6
|
"homepage": "https://github.com/OneKeyHQ/hardware-js-sdk#readme",
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
"url": "https://github.com/OneKeyHQ/hardware-js-sdk/issues"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@onekeyfe/hd-shared": "1.2.0-alpha.
|
|
29
|
-
"@onekeyfe/hd-transport": "1.2.0-alpha.
|
|
28
|
+
"@onekeyfe/hd-shared": "1.2.0-alpha.56",
|
|
29
|
+
"@onekeyfe/hd-transport": "1.2.0-alpha.56",
|
|
30
30
|
"axios": "1.15.2",
|
|
31
31
|
"bignumber.js": "^9.0.2",
|
|
32
32
|
"bytebuffer": "^5.0.1",
|
|
@@ -44,5 +44,5 @@
|
|
|
44
44
|
"@types/w3c-web-usb": "^1.0.10",
|
|
45
45
|
"@types/web-bluetooth": "^0.0.21"
|
|
46
46
|
},
|
|
47
|
-
"gitHead": "
|
|
47
|
+
"gitHead": "2c472748d67072307c21f8d33bc021cf18fe2ad7"
|
|
48
48
|
}
|
|
@@ -1698,17 +1698,22 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
1698
1698
|
progress: number | null
|
|
1699
1699
|
): Promise<TypedResponseMessage<'FilesystemFile'>> {
|
|
1700
1700
|
const typedCall = this.device.getCommands().typedCall.bind(this.device.getCommands());
|
|
1701
|
-
const writeRes = await typedCall(
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1701
|
+
const writeRes = await typedCall(
|
|
1702
|
+
'FilesystemFileWrite',
|
|
1703
|
+
'FilesystemFile',
|
|
1704
|
+
{
|
|
1705
|
+
file: {
|
|
1706
|
+
path: filePath,
|
|
1707
|
+
offset,
|
|
1708
|
+
total_size: totalFileSize,
|
|
1709
|
+
data: chunk,
|
|
1710
|
+
},
|
|
1711
|
+
overwrite,
|
|
1712
|
+
append: false,
|
|
1713
|
+
ui_percentage: progress ?? undefined,
|
|
1707
1714
|
},
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
ui_percentage: progress ?? undefined,
|
|
1711
|
-
});
|
|
1715
|
+
{ writeWithResponse: true }
|
|
1716
|
+
);
|
|
1712
1717
|
if (writeRes.type !== 'FilesystemFile') {
|
|
1713
1718
|
if ((writeRes as any).type === 'CallMethodError') {
|
|
1714
1719
|
if (((writeRes as any).message.error ?? '').indexOf(SESSION_ERROR) > -1) {
|
|
@@ -37,6 +37,7 @@ export type ProtocolV2FileWriteOptions = {
|
|
|
37
37
|
};
|
|
38
38
|
|
|
39
39
|
const MIN_FILE_CHUNK_SIZE = 64;
|
|
40
|
+
const FILE_TRANSFER_RATE_WINDOW_MS = 1000;
|
|
40
41
|
|
|
41
42
|
export function isProtocolV2ResponseTimeout(error: unknown) {
|
|
42
43
|
if (!error || typeof error !== 'object') return false;
|
|
@@ -121,6 +122,9 @@ export async function writeProtocolV2File(options: ProtocolV2FileWriteOptions) {
|
|
|
121
122
|
let chunks = 0;
|
|
122
123
|
let lastMessage: Record<string, unknown> | undefined;
|
|
123
124
|
const startTime = Date.now();
|
|
125
|
+
let rateWindowStartedAt = startTime;
|
|
126
|
+
let rateWindowStartedBytes = 0;
|
|
127
|
+
let rateBytesPerSecond: number | undefined;
|
|
124
128
|
|
|
125
129
|
while (written < dataLength) {
|
|
126
130
|
options.throwIfAborted?.();
|
|
@@ -178,14 +182,23 @@ export async function writeProtocolV2File(options: ProtocolV2FileWriteOptions) {
|
|
|
178
182
|
written =
|
|
179
183
|
rawProcessedByte === undefined ? written + chunk.byteLength : processedByte - startOffset;
|
|
180
184
|
chunks += 1;
|
|
181
|
-
const
|
|
185
|
+
const now = Date.now();
|
|
186
|
+
const elapsedMs = now - startTime;
|
|
182
187
|
const transferredBytes = Math.min(written, dataLength);
|
|
188
|
+
const rateWindowElapsedMs = now - rateWindowStartedAt;
|
|
189
|
+
if (rateWindowElapsedMs >= FILE_TRANSFER_RATE_WINDOW_MS) {
|
|
190
|
+
const rateWindowBytes = Math.max(transferredBytes - rateWindowStartedBytes, 0);
|
|
191
|
+
rateBytesPerSecond = Math.round((rateWindowBytes / rateWindowElapsedMs) * 1000);
|
|
192
|
+
rateWindowStartedAt = now;
|
|
193
|
+
rateWindowStartedBytes = transferredBytes;
|
|
194
|
+
} else if (rateBytesPerSecond === undefined && elapsedMs > 0) {
|
|
195
|
+
rateBytesPerSecond = Math.round((transferredBytes / elapsedMs) * 1000);
|
|
196
|
+
}
|
|
183
197
|
options.onProgress?.({
|
|
184
198
|
progress: getConfirmedProgress(startOffset + written, totalSize, written, dataLength),
|
|
185
199
|
transferredBytes,
|
|
186
200
|
totalBytes: dataLength,
|
|
187
|
-
rateBytesPerSecond
|
|
188
|
-
elapsedMs > 0 ? Math.round((transferredBytes / elapsedMs) * 1000) : undefined,
|
|
201
|
+
rateBytesPerSecond,
|
|
189
202
|
elapsedMs,
|
|
190
203
|
});
|
|
191
204
|
if (options.paceMs && options.paceMs > 0) {
|
|
@@ -15,5 +15,7 @@ export const ProtocolV2FirmwareTargetType = {
|
|
|
15
15
|
FW_MGMT_TARGET_SE04: 10,
|
|
16
16
|
} as const;
|
|
17
17
|
|
|
18
|
+
// 这里有意同时导出同名值与类型,以保持现有公共 API 不变。
|
|
19
|
+
// eslint-disable-next-line @typescript-eslint/no-redeclare
|
|
18
20
|
export type ProtocolV2FirmwareTargetType =
|
|
19
21
|
(typeof ProtocolV2FirmwareTargetType)[keyof typeof ProtocolV2FirmwareTargetType];
|