electron-updater 4.3.5 → 4.3.9

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.
Files changed (70) hide show
  1. package/LICENSE +22 -0
  2. package/out/AppAdapter.js +19 -28
  3. package/out/AppAdapter.js.map +1 -1
  4. package/out/AppImageUpdater.js +103 -173
  5. package/out/AppImageUpdater.js.map +1 -1
  6. package/out/AppUpdater.d.ts +1 -3
  7. package/out/AppUpdater.js +517 -773
  8. package/out/AppUpdater.js.map +1 -1
  9. package/out/BaseUpdater.js +79 -103
  10. package/out/BaseUpdater.js.map +1 -1
  11. package/out/DownloadedUpdateHelper.js +150 -224
  12. package/out/DownloadedUpdateHelper.js.map +1 -1
  13. package/out/ElectronAppAdapter.js +35 -63
  14. package/out/ElectronAppAdapter.js.map +1 -1
  15. package/out/MacUpdater.d.ts +1 -1
  16. package/out/MacUpdater.js +132 -182
  17. package/out/MacUpdater.js.map +1 -1
  18. package/out/NoOpLogger.d.ts +6 -0
  19. package/out/NoOpLogger.js +19 -0
  20. package/out/NoOpLogger.js.map +1 -0
  21. package/out/NsisUpdater.js +199 -331
  22. package/out/NsisUpdater.js.map +1 -1
  23. package/out/differentialDownloader/DataSplitter.js +180 -252
  24. package/out/differentialDownloader/DataSplitter.js.map +1 -1
  25. package/out/differentialDownloader/DifferentialDownloader.d.ts +3 -0
  26. package/out/differentialDownloader/DifferentialDownloader.js +243 -308
  27. package/out/differentialDownloader/DifferentialDownloader.js.map +1 -1
  28. package/out/differentialDownloader/FileWithEmbeddedBlockMapDifferentialDownloader.js +29 -65
  29. package/out/differentialDownloader/FileWithEmbeddedBlockMapDifferentialDownloader.js.map +1 -1
  30. package/out/differentialDownloader/GenericDifferentialDownloader.js +7 -21
  31. package/out/differentialDownloader/GenericDifferentialDownloader.js.map +1 -1
  32. package/out/differentialDownloader/ProgressDifferentialDownloadCallbackTransform.d.ts +32 -0
  33. package/out/differentialDownloader/ProgressDifferentialDownloadCallbackTransform.js +90 -0
  34. package/out/differentialDownloader/ProgressDifferentialDownloadCallbackTransform.js.map +1 -0
  35. package/out/differentialDownloader/downloadPlanBuilder.js +99 -124
  36. package/out/differentialDownloader/downloadPlanBuilder.js.map +1 -1
  37. package/out/differentialDownloader/multipleRangeDownloader.js +99 -148
  38. package/out/differentialDownloader/multipleRangeDownloader.js.map +1 -1
  39. package/out/electronHttpExecutor.js +73 -106
  40. package/out/electronHttpExecutor.js.map +1 -1
  41. package/out/event.d.ts +35 -0
  42. package/out/event.js +39 -0
  43. package/out/event.js.map +1 -0
  44. package/out/log.d.ts +11 -0
  45. package/out/log.js +19 -0
  46. package/out/log.js.map +1 -0
  47. package/out/main.d.ts +1 -4
  48. package/out/main.js +60 -212
  49. package/out/main.js.map +1 -1
  50. package/out/providerFactory.js +49 -105
  51. package/out/providerFactory.js.map +1 -1
  52. package/out/providers/BintrayProvider.d.ts +2 -2
  53. package/out/providers/BintrayProvider.js +40 -95
  54. package/out/providers/BintrayProvider.js.map +1 -1
  55. package/out/providers/GenericProvider.d.ts +2 -2
  56. package/out/providers/GenericProvider.js +46 -80
  57. package/out/providers/GenericProvider.js.map +1 -1
  58. package/out/providers/GitHubProvider.d.ts +2 -2
  59. package/out/providers/GitHubProvider.js +122 -201
  60. package/out/providers/GitHubProvider.js.map +1 -1
  61. package/out/providers/PrivateGitHubProvider.js +87 -165
  62. package/out/providers/PrivateGitHubProvider.js.map +1 -1
  63. package/out/providers/Provider.js +122 -173
  64. package/out/providers/Provider.js.map +1 -1
  65. package/out/util.d.ts +5 -0
  66. package/out/util.js +42 -0
  67. package/out/util.js.map +1 -0
  68. package/out/windowsExecutableCodeSignatureVerifier.js +99 -139
  69. package/out/windowsExecutableCodeSignatureVerifier.js.map +1 -1
  70. package/package.json +33 -31
@@ -1,73 +1,37 @@
1
1
  "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
2
+ Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.FileWithEmbeddedBlockMapDifferentialDownloader = void 0;
7
-
8
- function _fsExtra() {
9
- const data = require("fs-extra");
10
-
11
- _fsExtra = function () {
12
- return data;
13
- };
14
-
15
- return data;
4
+ const fs_extra_1 = require("fs-extra");
5
+ const DifferentialDownloader_1 = require("./DifferentialDownloader");
6
+ const zlib_1 = require("zlib");
7
+ class FileWithEmbeddedBlockMapDifferentialDownloader extends DifferentialDownloader_1.DifferentialDownloader {
8
+ async download() {
9
+ const packageInfo = this.blockAwareFileInfo;
10
+ const fileSize = packageInfo.size;
11
+ const offset = fileSize - (packageInfo.blockMapSize + 4);
12
+ this.fileMetadataBuffer = await this.readRemoteBytes(offset, fileSize - 1);
13
+ const newBlockMap = readBlockMap(this.fileMetadataBuffer.slice(0, this.fileMetadataBuffer.length - 4));
14
+ await this.doDownload(await readEmbeddedBlockMapData(this.options.oldFile), newBlockMap);
15
+ }
16
16
  }
17
-
18
- function _DifferentialDownloader() {
19
- const data = require("./DifferentialDownloader");
20
-
21
- _DifferentialDownloader = function () {
22
- return data;
23
- };
24
-
25
- return data;
26
- }
27
-
28
- function _zlib() {
29
- const data = require("zlib");
30
-
31
- _zlib = function () {
32
- return data;
33
- };
34
-
35
- return data;
36
- }
37
-
38
- class FileWithEmbeddedBlockMapDifferentialDownloader extends _DifferentialDownloader().DifferentialDownloader {
39
- async download() {
40
- const packageInfo = this.blockAwareFileInfo;
41
- const fileSize = packageInfo.size;
42
- const offset = fileSize - (packageInfo.blockMapSize + 4);
43
- this.fileMetadataBuffer = await this.readRemoteBytes(offset, fileSize - 1);
44
- const newBlockMap = readBlockMap(this.fileMetadataBuffer.slice(0, this.fileMetadataBuffer.length - 4));
45
- await this.doDownload((await readEmbeddedBlockMapData(this.options.oldFile)), newBlockMap);
46
- }
47
-
48
- }
49
-
50
17
  exports.FileWithEmbeddedBlockMapDifferentialDownloader = FileWithEmbeddedBlockMapDifferentialDownloader;
51
-
52
18
  function readBlockMap(data) {
53
- return JSON.parse((0, _zlib().inflateRawSync)(data).toString());
19
+ return JSON.parse(zlib_1.inflateRawSync(data).toString());
54
20
  }
55
-
56
21
  async function readEmbeddedBlockMapData(file) {
57
- const fd = await (0, _fsExtra().open)(file, "r");
58
-
59
- try {
60
- const fileSize = (await (0, _fsExtra().fstat)(fd)).size;
61
- const sizeBuffer = Buffer.allocUnsafe(4);
62
- await (0, _fsExtra().read)(fd, sizeBuffer, 0, sizeBuffer.length, fileSize - sizeBuffer.length);
63
- const dataBuffer = Buffer.allocUnsafe(sizeBuffer.readUInt32BE(0));
64
- await (0, _fsExtra().read)(fd, dataBuffer, 0, dataBuffer.length, fileSize - sizeBuffer.length - dataBuffer.length);
65
- await (0, _fsExtra().close)(fd);
66
- return readBlockMap(dataBuffer);
67
- } catch (e) {
68
- await (0, _fsExtra().close)(fd);
69
- throw e;
70
- }
71
- }
72
- // __ts-babel@6.0.4
22
+ const fd = await fs_extra_1.open(file, "r");
23
+ try {
24
+ const fileSize = (await fs_extra_1.fstat(fd)).size;
25
+ const sizeBuffer = Buffer.allocUnsafe(4);
26
+ await fs_extra_1.read(fd, sizeBuffer, 0, sizeBuffer.length, fileSize - sizeBuffer.length);
27
+ const dataBuffer = Buffer.allocUnsafe(sizeBuffer.readUInt32BE(0));
28
+ await fs_extra_1.read(fd, dataBuffer, 0, dataBuffer.length, fileSize - sizeBuffer.length - dataBuffer.length);
29
+ await fs_extra_1.close(fd);
30
+ return readBlockMap(dataBuffer);
31
+ }
32
+ catch (e) {
33
+ await fs_extra_1.close(fd);
34
+ throw e;
35
+ }
36
+ }
73
37
  //# sourceMappingURL=FileWithEmbeddedBlockMapDifferentialDownloader.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/differentialDownloader/FileWithEmbeddedBlockMapDifferentialDownloader.ts"],"names":[],"mappings":";;;;;;;AACA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;;AACA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;;AACA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAEM,MAAO,8CAAP,SAA8D,gDAA9D,CAAoF;AACxF,QAAM,QAAN,GAAc;AACZ,UAAM,WAAW,GAAG,KAAK,kBAAzB;AACA,UAAM,QAAQ,GAAG,WAAW,CAAC,IAA7B;AACA,UAAM,MAAM,GAAG,QAAQ,IAAI,WAAW,CAAC,YAAZ,GAA6B,CAAjC,CAAvB;AACA,SAAK,kBAAL,GAA0B,MAAM,KAAK,eAAL,CAAqB,MAArB,EAA6B,QAAQ,GAAG,CAAxC,CAAhC;AACA,UAAM,WAAW,GAAG,YAAY,CAAC,KAAK,kBAAL,CAAwB,KAAxB,CAA8B,CAA9B,EAAiC,KAAK,kBAAL,CAAwB,MAAxB,GAAiC,CAAlE,CAAD,CAAhC;AACA,UAAM,KAAK,UAAL,EAAgB,MAAM,wBAAwB,CAAC,KAAK,OAAL,CAAa,OAAd,CAA9C,GAAsE,WAAtE,CAAN;AACD;;AARuF;;;;AAW1F,SAAS,YAAT,CAAsB,IAAtB,EAAkC;AAChC,SAAO,IAAI,CAAC,KAAL,CAAW,4BAAe,IAAf,EAAqB,QAArB,EAAX,CAAP;AACD;;AAED,eAAe,wBAAf,CAAwC,IAAxC,EAAoD;AAClD,QAAM,EAAE,GAAG,MAAM,qBAAK,IAAL,EAAW,GAAX,CAAjB;;AACA,MAAI;AACF,UAAM,QAAQ,GAAG,CAAC,MAAM,sBAAM,EAAN,CAAP,EAAkB,IAAnC;AACA,UAAM,UAAU,GAAG,MAAM,CAAC,WAAP,CAAmB,CAAnB,CAAnB;AACA,UAAM,qBAAK,EAAL,EAAS,UAAT,EAAqB,CAArB,EAAwB,UAAU,CAAC,MAAnC,EAA2C,QAAQ,GAAG,UAAU,CAAC,MAAjE,CAAN;AAEA,UAAM,UAAU,GAAG,MAAM,CAAC,WAAP,CAAmB,UAAU,CAAC,YAAX,CAAwB,CAAxB,CAAnB,CAAnB;AACA,UAAM,qBAAK,EAAL,EAAS,UAAT,EAAqB,CAArB,EAAwB,UAAU,CAAC,MAAnC,EAA2C,QAAQ,GAAG,UAAU,CAAC,MAAtB,GAA+B,UAAU,CAAC,MAArF,CAAN;AACA,UAAM,sBAAM,EAAN,CAAN;AAEA,WAAO,YAAY,CAAC,UAAD,CAAnB;AACD,GAVD,CAWA,OAAO,CAAP,EAAU;AACR,UAAM,sBAAM,EAAN,CAAN;AACA,UAAM,CAAN;AACD;AACF,C","sourcesContent":["import { BlockMap } from \"builder-util-runtime/out/blockMapApi\"\nimport { close, fstat, open, read } from \"fs-extra\"\nimport { DifferentialDownloader } from \"./DifferentialDownloader\"\nimport { inflateRawSync } from \"zlib\"\n\nexport class FileWithEmbeddedBlockMapDifferentialDownloader extends DifferentialDownloader {\n async download(): Promise<void> {\n const packageInfo = this.blockAwareFileInfo\n const fileSize = packageInfo.size!!\n const offset = fileSize - (packageInfo.blockMapSize!! + 4)\n this.fileMetadataBuffer = await this.readRemoteBytes(offset, fileSize - 1)\n const newBlockMap = readBlockMap(this.fileMetadataBuffer.slice(0, this.fileMetadataBuffer.length - 4))\n await this.doDownload(await readEmbeddedBlockMapData(this.options.oldFile), newBlockMap)\n }\n}\n\nfunction readBlockMap(data: Buffer): BlockMap {\n return JSON.parse(inflateRawSync(data).toString())\n}\n\nasync function readEmbeddedBlockMapData(file: string): Promise<BlockMap> {\n const fd = await open(file, \"r\")\n try {\n const fileSize = (await fstat(fd)).size\n const sizeBuffer = Buffer.allocUnsafe(4)\n await read(fd, sizeBuffer, 0, sizeBuffer.length, fileSize - sizeBuffer.length)\n\n const dataBuffer = Buffer.allocUnsafe(sizeBuffer.readUInt32BE(0))\n await read(fd, dataBuffer, 0, dataBuffer.length, fileSize - sizeBuffer.length - dataBuffer.length)\n await close(fd)\n\n return readBlockMap(dataBuffer)\n }\n catch (e) {\n await close(fd)\n throw e\n }\n}"],"sourceRoot":""}
1
+ {"version":3,"file":"FileWithEmbeddedBlockMapDifferentialDownloader.js","sourceRoot":"","sources":["../../src/differentialDownloader/FileWithEmbeddedBlockMapDifferentialDownloader.ts"],"names":[],"mappings":";;;AACA,uCAAmD;AACnD,qEAAiE;AACjE,+BAAqC;AAErC,MAAa,8CAA+C,SAAQ,+CAAsB;IACxF,KAAK,CAAC,QAAQ;QACZ,MAAM,WAAW,GAAG,IAAI,CAAC,kBAAkB,CAAA;QAC3C,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAK,CAAA;QAClC,MAAM,MAAM,GAAG,QAAQ,GAAG,CAAC,WAAW,CAAC,YAAa,GAAG,CAAC,CAAC,CAAA;QACzD,IAAI,CAAC,kBAAkB,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,QAAQ,GAAG,CAAC,CAAC,CAAA;QAC1E,MAAM,WAAW,GAAG,YAAY,CAAC,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,kBAAkB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAA;QACtG,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,wBAAwB,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,WAAW,CAAC,CAAA;IAC1F,CAAC;CACF;AATD,wGASC;AAED,SAAS,YAAY,CAAC,IAAY;IAChC,OAAO,IAAI,CAAC,KAAK,CAAC,qBAAc,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAA;AACpD,CAAC;AAED,KAAK,UAAU,wBAAwB,CAAC,IAAY;IAClD,MAAM,EAAE,GAAG,MAAM,eAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;IAChC,IAAI;QACF,MAAM,QAAQ,GAAG,CAAC,MAAM,gBAAK,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;QACvC,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAA;QACxC,MAAM,eAAI,CAAC,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,CAAC,MAAM,EAAE,QAAQ,GAAG,UAAU,CAAC,MAAM,CAAC,CAAA;QAE9E,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAA;QACjE,MAAM,eAAI,CAAC,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,CAAC,MAAM,EAAE,QAAQ,GAAG,UAAU,CAAC,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,CAAA;QAClG,MAAM,gBAAK,CAAC,EAAE,CAAC,CAAA;QAEf,OAAO,YAAY,CAAC,UAAU,CAAC,CAAA;KAChC;IAAC,OAAO,CAAC,EAAE;QACV,MAAM,gBAAK,CAAC,EAAE,CAAC,CAAA;QACf,MAAM,CAAC,CAAA;KACR;AACH,CAAC","sourcesContent":["import { BlockMap } from \"builder-util-runtime/out/blockMapApi\"\nimport { close, fstat, open, read } from \"fs-extra\"\nimport { DifferentialDownloader } from \"./DifferentialDownloader\"\nimport { inflateRawSync } from \"zlib\"\n\nexport class FileWithEmbeddedBlockMapDifferentialDownloader extends DifferentialDownloader {\n async download(): Promise<void> {\n const packageInfo = this.blockAwareFileInfo\n const fileSize = packageInfo.size!\n const offset = fileSize - (packageInfo.blockMapSize! + 4)\n this.fileMetadataBuffer = await this.readRemoteBytes(offset, fileSize - 1)\n const newBlockMap = readBlockMap(this.fileMetadataBuffer.slice(0, this.fileMetadataBuffer.length - 4))\n await this.doDownload(await readEmbeddedBlockMapData(this.options.oldFile), newBlockMap)\n }\n}\n\nfunction readBlockMap(data: Buffer): BlockMap {\n return JSON.parse(inflateRawSync(data).toString())\n}\n\nasync function readEmbeddedBlockMapData(file: string): Promise<BlockMap> {\n const fd = await open(file, \"r\")\n try {\n const fileSize = (await fstat(fd)).size\n const sizeBuffer = Buffer.allocUnsafe(4)\n await read(fd, sizeBuffer, 0, sizeBuffer.length, fileSize - sizeBuffer.length)\n\n const dataBuffer = Buffer.allocUnsafe(sizeBuffer.readUInt32BE(0))\n await read(fd, dataBuffer, 0, dataBuffer.length, fileSize - sizeBuffer.length - dataBuffer.length)\n await close(fd)\n\n return readBlockMap(dataBuffer)\n } catch (e) {\n await close(fd)\n throw e\n }\n}\n"]}
@@ -1,25 +1,11 @@
1
1
  "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
2
+ Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.GenericDifferentialDownloader = void 0;
7
-
8
- function _DifferentialDownloader() {
9
- const data = require("./DifferentialDownloader");
10
-
11
- _DifferentialDownloader = function () {
12
- return data;
13
- };
14
-
15
- return data;
4
+ const DifferentialDownloader_1 = require("./DifferentialDownloader");
5
+ class GenericDifferentialDownloader extends DifferentialDownloader_1.DifferentialDownloader {
6
+ download(oldBlockMap, newBlockMap) {
7
+ return this.doDownload(oldBlockMap, newBlockMap);
8
+ }
16
9
  }
17
-
18
- class GenericDifferentialDownloader extends _DifferentialDownloader().DifferentialDownloader {
19
- download(oldBlockMap, newBlockMap) {
20
- return this.doDownload(oldBlockMap, newBlockMap);
21
- }
22
-
23
- } exports.GenericDifferentialDownloader = GenericDifferentialDownloader;
24
- // __ts-babel@6.0.4
10
+ exports.GenericDifferentialDownloader = GenericDifferentialDownloader;
25
11
  //# sourceMappingURL=GenericDifferentialDownloader.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/differentialDownloader/GenericDifferentialDownloader.ts"],"names":[],"mappings":";;;;;;;AACA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAEM,MAAO,6BAAP,SAA6C,gDAA7C,CAAmE;AACvE,EAAA,QAAQ,CAAC,WAAD,EAAwB,WAAxB,EAA6C;AACnD,WAAO,KAAK,UAAL,CAAgB,WAAhB,EAA6B,WAA7B,CAAP;AACD;;AAHsE,C","sourcesContent":["import { BlockMap } from \"builder-util-runtime/out/blockMapApi\"\nimport { DifferentialDownloader } from \"./DifferentialDownloader\"\n\nexport class GenericDifferentialDownloader extends DifferentialDownloader {\n download(oldBlockMap: BlockMap, newBlockMap: BlockMap): Promise<any> {\n return this.doDownload(oldBlockMap, newBlockMap)\n }\n}"],"sourceRoot":""}
1
+ {"version":3,"file":"GenericDifferentialDownloader.js","sourceRoot":"","sources":["../../src/differentialDownloader/GenericDifferentialDownloader.ts"],"names":[],"mappings":";;;AACA,qEAAiE;AAEjE,MAAa,6BAA8B,SAAQ,+CAAsB;IACvE,QAAQ,CAAC,WAAqB,EAAE,WAAqB;QACnD,OAAO,IAAI,CAAC,UAAU,CAAC,WAAW,EAAE,WAAW,CAAC,CAAA;IAClD,CAAC;CACF;AAJD,sEAIC","sourcesContent":["import { BlockMap } from \"builder-util-runtime/out/blockMapApi\"\nimport { DifferentialDownloader } from \"./DifferentialDownloader\"\n\nexport class GenericDifferentialDownloader extends DifferentialDownloader {\n download(oldBlockMap: BlockMap, newBlockMap: BlockMap): Promise<any> {\n return this.doDownload(oldBlockMap, newBlockMap)\n }\n}\n"]}
@@ -0,0 +1,32 @@
1
+ /// <reference types="node" />
2
+ import { Transform } from "stream";
3
+ import { CancellationToken } from "builder-util-runtime";
4
+ export interface ProgressInfo {
5
+ total: number;
6
+ delta: number;
7
+ transferred: number;
8
+ percent: number;
9
+ bytesPerSecond: number;
10
+ }
11
+ export interface ProgressDifferentialDownloadInfo {
12
+ expectedByteCounts: Array<number>;
13
+ grandTotal: number;
14
+ }
15
+ export declare class ProgressDifferentialDownloadCallbackTransform extends Transform {
16
+ private readonly progressDifferentialDownloadInfo;
17
+ private readonly cancellationToken;
18
+ private readonly onProgress;
19
+ private start;
20
+ private transferred;
21
+ private delta;
22
+ private expectedBytes;
23
+ private index;
24
+ private operationType;
25
+ private nextUpdate;
26
+ constructor(progressDifferentialDownloadInfo: ProgressDifferentialDownloadInfo, cancellationToken: CancellationToken, onProgress: (info: ProgressInfo) => any);
27
+ _transform(chunk: any, encoding: string, callback: any): void;
28
+ beginFileCopy(): void;
29
+ beginRangeDownload(): void;
30
+ endRangeDownload(): void;
31
+ _flush(callback: any): void;
32
+ }
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ProgressDifferentialDownloadCallbackTransform = void 0;
4
+ const stream_1 = require("stream");
5
+ var OperationKind;
6
+ (function (OperationKind) {
7
+ OperationKind[OperationKind["COPY"] = 0] = "COPY";
8
+ OperationKind[OperationKind["DOWNLOAD"] = 1] = "DOWNLOAD";
9
+ })(OperationKind || (OperationKind = {}));
10
+ class ProgressDifferentialDownloadCallbackTransform extends stream_1.Transform {
11
+ constructor(progressDifferentialDownloadInfo, cancellationToken, onProgress) {
12
+ super();
13
+ this.progressDifferentialDownloadInfo = progressDifferentialDownloadInfo;
14
+ this.cancellationToken = cancellationToken;
15
+ this.onProgress = onProgress;
16
+ this.start = Date.now();
17
+ this.transferred = 0;
18
+ this.delta = 0;
19
+ this.expectedBytes = 0;
20
+ this.index = 0;
21
+ this.operationType = OperationKind.COPY;
22
+ this.nextUpdate = this.start + 1000;
23
+ }
24
+ _transform(chunk, encoding, callback) {
25
+ if (this.cancellationToken.cancelled) {
26
+ callback(new Error("cancelled"), null);
27
+ return;
28
+ }
29
+ // Don't send progress update when copying from disk
30
+ if (this.operationType == OperationKind.COPY) {
31
+ callback(null, chunk);
32
+ return;
33
+ }
34
+ this.transferred += chunk.length;
35
+ this.delta += chunk.length;
36
+ const now = Date.now();
37
+ if (now >= this.nextUpdate &&
38
+ this.transferred !== this.expectedBytes /* will be emitted by endRangeDownload() */ &&
39
+ this.transferred !== this.progressDifferentialDownloadInfo.grandTotal /* will be emitted on _flush */) {
40
+ this.nextUpdate = now + 1000;
41
+ this.onProgress({
42
+ total: this.progressDifferentialDownloadInfo.grandTotal,
43
+ delta: this.delta,
44
+ transferred: this.transferred,
45
+ percent: (this.transferred / this.progressDifferentialDownloadInfo.grandTotal) * 100,
46
+ bytesPerSecond: Math.round(this.transferred / ((now - this.start) / 1000)),
47
+ });
48
+ this.delta = 0;
49
+ }
50
+ callback(null, chunk);
51
+ }
52
+ beginFileCopy() {
53
+ this.operationType = OperationKind.COPY;
54
+ }
55
+ beginRangeDownload() {
56
+ this.operationType = OperationKind.DOWNLOAD;
57
+ this.expectedBytes += this.progressDifferentialDownloadInfo.expectedByteCounts[this.index++];
58
+ }
59
+ endRangeDownload() {
60
+ // _flush() will doour final 100%
61
+ if (this.transferred !== this.progressDifferentialDownloadInfo.grandTotal) {
62
+ this.onProgress({
63
+ total: this.progressDifferentialDownloadInfo.grandTotal,
64
+ delta: this.delta,
65
+ transferred: this.transferred,
66
+ percent: (this.transferred / this.progressDifferentialDownloadInfo.grandTotal) * 100,
67
+ bytesPerSecond: Math.round(this.transferred / ((Date.now() - this.start) / 1000)),
68
+ });
69
+ }
70
+ }
71
+ // Called when we are 100% done with the connection/download
72
+ _flush(callback) {
73
+ if (this.cancellationToken.cancelled) {
74
+ callback(new Error("cancelled"));
75
+ return;
76
+ }
77
+ this.onProgress({
78
+ total: this.progressDifferentialDownloadInfo.grandTotal,
79
+ delta: this.delta,
80
+ transferred: this.transferred,
81
+ percent: 100,
82
+ bytesPerSecond: Math.round(this.transferred / ((Date.now() - this.start) / 1000)),
83
+ });
84
+ this.delta = 0;
85
+ this.transferred = 0;
86
+ callback(null);
87
+ }
88
+ }
89
+ exports.ProgressDifferentialDownloadCallbackTransform = ProgressDifferentialDownloadCallbackTransform;
90
+ //# sourceMappingURL=ProgressDifferentialDownloadCallbackTransform.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProgressDifferentialDownloadCallbackTransform.js","sourceRoot":"","sources":["../../src/differentialDownloader/ProgressDifferentialDownloadCallbackTransform.ts"],"names":[],"mappings":"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","sourcesContent":["import { Transform } from \"stream\"\nimport { CancellationToken } from \"builder-util-runtime\"\n\nenum OperationKind {\n COPY,\n DOWNLOAD,\n}\n\nexport interface ProgressInfo {\n total: number\n delta: number\n transferred: number\n percent: number\n bytesPerSecond: number\n}\n\nexport interface ProgressDifferentialDownloadInfo {\n expectedByteCounts: Array<number>\n grandTotal: number\n}\n\nexport class ProgressDifferentialDownloadCallbackTransform extends Transform {\n private start = Date.now()\n private transferred = 0\n private delta = 0\n private expectedBytes = 0\n private index = 0\n private operationType = OperationKind.COPY\n\n private nextUpdate = this.start + 1000\n\n constructor(\n private readonly progressDifferentialDownloadInfo: ProgressDifferentialDownloadInfo,\n private readonly cancellationToken: CancellationToken,\n private readonly onProgress: (info: ProgressInfo) => any\n ) {\n super()\n }\n\n _transform(chunk: any, encoding: string, callback: any) {\n if (this.cancellationToken.cancelled) {\n callback(new Error(\"cancelled\"), null)\n return\n }\n\n // Don't send progress update when copying from disk\n if (this.operationType == OperationKind.COPY) {\n callback(null, chunk)\n return\n }\n\n this.transferred += chunk.length\n this.delta += chunk.length\n\n const now = Date.now()\n if (\n now >= this.nextUpdate &&\n this.transferred !== this.expectedBytes /* will be emitted by endRangeDownload() */ &&\n this.transferred !== this.progressDifferentialDownloadInfo.grandTotal /* will be emitted on _flush */\n ) {\n this.nextUpdate = now + 1000\n\n this.onProgress({\n total: this.progressDifferentialDownloadInfo.grandTotal,\n delta: this.delta,\n transferred: this.transferred,\n percent: (this.transferred / this.progressDifferentialDownloadInfo.grandTotal) * 100,\n bytesPerSecond: Math.round(this.transferred / ((now - this.start) / 1000)),\n })\n this.delta = 0\n }\n\n callback(null, chunk)\n }\n\n beginFileCopy(): void {\n this.operationType = OperationKind.COPY\n }\n\n beginRangeDownload(): void {\n this.operationType = OperationKind.DOWNLOAD\n\n this.expectedBytes += this.progressDifferentialDownloadInfo.expectedByteCounts[this.index++]\n }\n\n endRangeDownload(): void {\n // _flush() will doour final 100%\n if (this.transferred !== this.progressDifferentialDownloadInfo.grandTotal) {\n this.onProgress({\n total: this.progressDifferentialDownloadInfo.grandTotal,\n delta: this.delta,\n transferred: this.transferred,\n percent: (this.transferred / this.progressDifferentialDownloadInfo.grandTotal) * 100,\n bytesPerSecond: Math.round(this.transferred / ((Date.now() - this.start) / 1000)),\n })\n }\n }\n\n // Called when we are 100% done with the connection/download\n _flush(callback: any): void {\n if (this.cancellationToken.cancelled) {\n callback(new Error(\"cancelled\"))\n return\n }\n\n this.onProgress({\n total: this.progressDifferentialDownloadInfo.grandTotal,\n delta: this.delta,\n transferred: this.transferred,\n percent: 100,\n bytesPerSecond: Math.round(this.transferred / ((Date.now() - this.start) / 1000)),\n })\n this.delta = 0\n this.transferred = 0\n\n callback(null)\n }\n}\n"]}
@@ -1,139 +1,114 @@
1
1
  "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.computeOperations = computeOperations;
7
- exports.OperationKind = void 0;
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.computeOperations = exports.OperationKind = void 0;
8
4
  var OperationKind;
9
- exports.OperationKind = OperationKind;
10
-
11
5
  (function (OperationKind) {
12
- OperationKind[OperationKind["COPY"] = 0] = "COPY";
13
- OperationKind[OperationKind["DOWNLOAD"] = 1] = "DOWNLOAD";
14
- })(OperationKind || (exports.OperationKind = OperationKind = {}));
15
-
6
+ OperationKind[OperationKind["COPY"] = 0] = "COPY";
7
+ OperationKind[OperationKind["DOWNLOAD"] = 1] = "DOWNLOAD";
8
+ })(OperationKind = exports.OperationKind || (exports.OperationKind = {}));
16
9
  function computeOperations(oldBlockMap, newBlockMap, logger) {
17
- const nameToOldBlocks = buildBlockFileMap(oldBlockMap.files);
18
- const nameToNewBlocks = buildBlockFileMap(newBlockMap.files);
19
- let lastOperation = null; // for now only one file is supported in block map
20
-
21
- const blockMapFile = newBlockMap.files[0];
22
- const operations = [];
23
- const name = blockMapFile.name;
24
- const oldEntry = nameToOldBlocks.get(name);
25
-
26
- if (oldEntry == null) {
27
- // new file (unrealistic case for now, because in any case both blockmap contain the only file named as "file")
28
- throw new Error(`no file ${name} in old blockmap`);
29
- }
30
-
31
- const newFile = nameToNewBlocks.get(name);
32
- let changedBlockCount = 0;
33
- const {
34
- checksumToOffset: checksumToOldOffset,
35
- checksumToOldSize
36
- } = buildChecksumMap(nameToOldBlocks.get(name), oldEntry.offset, logger);
37
- let newOffset = blockMapFile.offset;
38
-
39
- for (let i = 0; i < newFile.checksums.length; newOffset += newFile.sizes[i], i++) {
40
- const blockSize = newFile.sizes[i];
41
- const checksum = newFile.checksums[i];
42
- let oldOffset = checksumToOldOffset.get(checksum);
43
-
44
- if (oldOffset != null && checksumToOldSize.get(checksum) !== blockSize) {
45
- logger.warn(`Checksum ("${checksum}") matches, but size differs (old: ${checksumToOldSize.get(checksum)}, new: ${blockSize})`);
46
- oldOffset = undefined;
10
+ const nameToOldBlocks = buildBlockFileMap(oldBlockMap.files);
11
+ const nameToNewBlocks = buildBlockFileMap(newBlockMap.files);
12
+ let lastOperation = null;
13
+ // for now only one file is supported in block map
14
+ const blockMapFile = newBlockMap.files[0];
15
+ const operations = [];
16
+ const name = blockMapFile.name;
17
+ const oldEntry = nameToOldBlocks.get(name);
18
+ if (oldEntry == null) {
19
+ // new file (unrealistic case for now, because in any case both blockmap contain the only file named as "file")
20
+ throw new Error(`no file ${name} in old blockmap`);
21
+ }
22
+ const newFile = nameToNewBlocks.get(name);
23
+ let changedBlockCount = 0;
24
+ const { checksumToOffset: checksumToOldOffset, checksumToOldSize } = buildChecksumMap(nameToOldBlocks.get(name), oldEntry.offset, logger);
25
+ let newOffset = blockMapFile.offset;
26
+ for (let i = 0; i < newFile.checksums.length; newOffset += newFile.sizes[i], i++) {
27
+ const blockSize = newFile.sizes[i];
28
+ const checksum = newFile.checksums[i];
29
+ let oldOffset = checksumToOldOffset.get(checksum);
30
+ if (oldOffset != null && checksumToOldSize.get(checksum) !== blockSize) {
31
+ logger.warn(`Checksum ("${checksum}") matches, but size differs (old: ${checksumToOldSize.get(checksum)}, new: ${blockSize})`);
32
+ oldOffset = undefined;
33
+ }
34
+ if (oldOffset === undefined) {
35
+ // download data from new file
36
+ changedBlockCount++;
37
+ if (lastOperation != null && lastOperation.kind === OperationKind.DOWNLOAD && lastOperation.end === newOffset) {
38
+ lastOperation.end += blockSize;
39
+ }
40
+ else {
41
+ lastOperation = {
42
+ kind: OperationKind.DOWNLOAD,
43
+ start: newOffset,
44
+ end: newOffset + blockSize,
45
+ // oldBlocks: null,
46
+ };
47
+ validateAndAdd(lastOperation, operations, checksum, i);
48
+ }
49
+ }
50
+ else {
51
+ // reuse data from old file
52
+ if (lastOperation != null && lastOperation.kind === OperationKind.COPY && lastOperation.end === oldOffset) {
53
+ lastOperation.end += blockSize;
54
+ // lastOperation.oldBlocks!!.push(checksum)
55
+ }
56
+ else {
57
+ lastOperation = {
58
+ kind: OperationKind.COPY,
59
+ start: oldOffset,
60
+ end: oldOffset + blockSize,
61
+ // oldBlocks: [checksum]
62
+ };
63
+ validateAndAdd(lastOperation, operations, checksum, i);
64
+ }
65
+ }
47
66
  }
48
-
49
- if (oldOffset === undefined) {
50
- // download data from new file
51
- changedBlockCount++;
52
-
53
- if (lastOperation != null && lastOperation.kind === OperationKind.DOWNLOAD && lastOperation.end === newOffset) {
54
- lastOperation.end += blockSize;
55
- } else {
56
- lastOperation = {
57
- kind: OperationKind.DOWNLOAD,
58
- start: newOffset,
59
- end: newOffset + blockSize
60
- };
61
- validateAndAdd(lastOperation, operations, checksum, i);
62
- }
63
- } else {
64
- // reuse data from old file
65
- if (lastOperation != null && lastOperation.kind === OperationKind.COPY && lastOperation.end === oldOffset) {
66
- lastOperation.end += blockSize; // lastOperation.oldBlocks!!.push(checksum)
67
- } else {
68
- lastOperation = {
69
- kind: OperationKind.COPY,
70
- start: oldOffset,
71
- end: oldOffset + blockSize
72
- };
73
- validateAndAdd(lastOperation, operations, checksum, i);
74
- }
67
+ if (changedBlockCount > 0) {
68
+ logger.info(`File${blockMapFile.name === "file" ? "" : " " + blockMapFile.name} has ${changedBlockCount} changed blocks`);
75
69
  }
76
- }
77
-
78
- if (changedBlockCount > 0) {
79
- logger.info(`File${blockMapFile.name === "file" ? "" : " " + blockMapFile.name} has ${changedBlockCount} changed blocks`);
80
- }
81
-
82
- return operations;
70
+ return operations;
83
71
  }
84
-
72
+ exports.computeOperations = computeOperations;
85
73
  const isValidateOperationRange = process.env.DIFFERENTIAL_DOWNLOAD_PLAN_BUILDER_VALIDATE_RANGES === "true";
86
-
87
74
  function validateAndAdd(operation, operations, checksum, index) {
88
- if (isValidateOperationRange && operations.length !== 0) {
89
- const lastOperation = operations[operations.length - 1];
90
-
91
- if (lastOperation.kind === operation.kind && operation.start < lastOperation.end && operation.start > lastOperation.start) {
92
- const min = [lastOperation.start, lastOperation.end, operation.start, operation.end].reduce((p, v) => p < v ? p : v);
93
- throw new Error(`operation (block index: ${index}, checksum: ${checksum}, kind: ${OperationKind[operation.kind]}) overlaps previous operation (checksum: ${checksum}):\n` + `abs: ${lastOperation.start} until ${lastOperation.end} and ${operation.start} until ${operation.end}\n` + `rel: ${lastOperation.start - min} until ${lastOperation.end - min} and ${operation.start - min} until ${operation.end - min}`);
75
+ if (isValidateOperationRange && operations.length !== 0) {
76
+ const lastOperation = operations[operations.length - 1];
77
+ if (lastOperation.kind === operation.kind && operation.start < lastOperation.end && operation.start > lastOperation.start) {
78
+ const min = [lastOperation.start, lastOperation.end, operation.start, operation.end].reduce((p, v) => (p < v ? p : v));
79
+ throw new Error(`operation (block index: ${index}, checksum: ${checksum}, kind: ${OperationKind[operation.kind]}) overlaps previous operation (checksum: ${checksum}):\n` +
80
+ `abs: ${lastOperation.start} until ${lastOperation.end} and ${operation.start} until ${operation.end}\n` +
81
+ `rel: ${lastOperation.start - min} until ${lastOperation.end - min} and ${operation.start - min} until ${operation.end - min}`);
82
+ }
94
83
  }
95
- }
96
-
97
- operations.push(operation);
98
- } // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
99
-
100
-
84
+ operations.push(operation);
85
+ }
86
+ // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
101
87
  function buildChecksumMap(file, fileOffset, logger) {
102
- const checksumToOffset = new Map();
103
- const checksumToSize = new Map();
104
- let offset = fileOffset;
105
- const debugLog = logger.debug;
106
-
107
- for (let i = 0; i < file.checksums.length; i++) {
108
- const checksum = file.checksums[i];
109
- const size = file.sizes[i];
110
- const existing = checksumToSize.get(checksum);
111
-
112
- if (existing === undefined) {
113
- checksumToOffset.set(checksum, offset);
114
- checksumToSize.set(checksum, size);
115
- } else if (debugLog != null) {
116
- const sizeExplanation = existing === size ? "(same size)" : `(size: ${existing}, this size: ${size})`;
117
- debugLog(`${checksum} duplicated in blockmap ${sizeExplanation}, it doesn't lead to broken differential downloader, just corresponding block will be skipped)`);
88
+ const checksumToOffset = new Map();
89
+ const checksumToSize = new Map();
90
+ let offset = fileOffset;
91
+ for (let i = 0; i < file.checksums.length; i++) {
92
+ const checksum = file.checksums[i];
93
+ const size = file.sizes[i];
94
+ const existing = checksumToSize.get(checksum);
95
+ if (existing === undefined) {
96
+ checksumToOffset.set(checksum, offset);
97
+ checksumToSize.set(checksum, size);
98
+ }
99
+ else if (logger.debug != null) {
100
+ const sizeExplanation = existing === size ? "(same size)" : `(size: ${existing}, this size: ${size})`;
101
+ logger.debug(`${checksum} duplicated in blockmap ${sizeExplanation}, it doesn't lead to broken differential downloader, just corresponding block will be skipped)`);
102
+ }
103
+ offset += size;
118
104
  }
119
-
120
- offset += size;
121
- }
122
-
123
- return {
124
- checksumToOffset,
125
- checksumToOldSize: checksumToSize
126
- };
105
+ return { checksumToOffset, checksumToOldSize: checksumToSize };
127
106
  }
128
-
129
107
  function buildBlockFileMap(list) {
130
- const result = new Map();
131
-
132
- for (const item of list) {
133
- result.set(item.name, item);
134
- }
135
-
136
- return result;
137
- }
138
- // __ts-babel@6.0.4
108
+ const result = new Map();
109
+ for (const item of list) {
110
+ result.set(item.name, item);
111
+ }
112
+ return result;
113
+ }
139
114
  //# sourceMappingURL=downloadPlanBuilder.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/differentialDownloader/downloadPlanBuilder.ts"],"names":[],"mappings":";;;;;;;AAGA,IAAY,aAAZ;;;AAAA,CAAA,UAAY,aAAZ,EAAyB;AACvB,EAAA,aAAA,CAAA,aAAA,CAAA,MAAA,CAAA,GAAA,CAAA,CAAA,GAAA,MAAA;AAAM,EAAA,aAAA,CAAA,aAAA,CAAA,UAAA,CAAA,GAAA,CAAA,CAAA,GAAA,UAAA;AACP,CAFD,EAAY,aAAa,6BAAb,aAAa,GAAA,EAAA,CAAzB;;AAgBM,SAAU,iBAAV,CAA4B,WAA5B,EAAmD,WAAnD,EAA0E,MAA1E,EAAwF;AAC5F,QAAM,eAAe,GAAG,iBAAiB,CAAC,WAAW,CAAC,KAAb,CAAzC;AACA,QAAM,eAAe,GAAG,iBAAiB,CAAC,WAAW,CAAC,KAAb,CAAzC;AAEA,MAAI,aAAa,GAAqB,IAAtC,CAJ4F,CAM5F;;AACA,QAAM,YAAY,GAAG,WAAW,CAAC,KAAZ,CAAkB,CAAlB,CAArB;AACA,QAAM,UAAU,GAAqB,EAArC;AACA,QAAM,IAAI,GAAG,YAAY,CAAC,IAA1B;AACA,QAAM,QAAQ,GAAG,eAAe,CAAC,GAAhB,CAAoB,IAApB,CAAjB;;AACA,MAAI,QAAQ,IAAI,IAAhB,EAAsB;AACpB;AACA,UAAM,IAAI,KAAJ,CAAU,WAAW,IAAI,kBAAzB,CAAN;AACD;;AAED,QAAM,OAAO,GAAG,eAAe,CAAC,GAAhB,CAAoB,IAApB,CAAhB;AACA,MAAI,iBAAiB,GAAG,CAAxB;AAEA,QAAM;AAAC,IAAA,gBAAgB,EAAE,mBAAnB;AAAwC,IAAA;AAAxC,MAA6D,gBAAgB,CAAC,eAAe,CAAC,GAAhB,CAAoB,IAApB,CAAD,EAA8B,QAAQ,CAAC,MAAvC,EAA+C,MAA/C,CAAnF;AAEA,MAAI,SAAS,GAAG,YAAY,CAAC,MAA7B;;AACA,OAAK,IAAI,CAAC,GAAG,CAAb,EAAgB,CAAC,GAAG,OAAO,CAAC,SAAR,CAAkB,MAAtC,EAA8C,SAAS,IAAI,OAAO,CAAC,KAAR,CAAc,CAAd,CAAb,EAA+B,CAAC,EAA9E,EAAkF;AAChF,UAAM,SAAS,GAAG,OAAO,CAAC,KAAR,CAAc,CAAd,CAAlB;AACA,UAAM,QAAQ,GAAG,OAAO,CAAC,SAAR,CAAkB,CAAlB,CAAjB;AACA,QAAI,SAAS,GAAG,mBAAmB,CAAC,GAApB,CAAwB,QAAxB,CAAhB;;AACA,QAAI,SAAS,IAAI,IAAb,IAAqB,iBAAiB,CAAC,GAAlB,CAAsB,QAAtB,MAAoC,SAA7D,EAAwE;AACtE,MAAA,MAAM,CAAC,IAAP,CAAY,cAAc,QAAQ,sCAAsC,iBAAiB,CAAC,GAAlB,CAAsB,QAAtB,CAA+B,UAAU,SAAS,GAA1H;AACA,MAAA,SAAS,GAAG,SAAZ;AACD;;AAED,QAAI,SAAS,KAAK,SAAlB,EAA6B;AAC3B;AACA,MAAA,iBAAiB;;AAEjB,UAAI,aAAa,IAAI,IAAjB,IAAyB,aAAa,CAAC,IAAd,KAAuB,aAAa,CAAC,QAA9D,IAA0E,aAAa,CAAC,GAAd,KAAsB,SAApG,EAA+G;AAC7G,QAAA,aAAa,CAAC,GAAd,IAAqB,SAArB;AACD,OAFD,MAGK;AACH,QAAA,aAAa,GAAG;AACd,UAAA,IAAI,EAAE,aAAa,CAAC,QADN;AAEd,UAAA,KAAK,EAAE,SAFO;AAGd,UAAA,GAAG,EAAE,SAAS,GAAG;AAHH,SAAhB;AAMA,QAAA,cAAc,CAAC,aAAD,EAAgB,UAAhB,EAA4B,QAA5B,EAAsC,CAAtC,CAAd;AACD;AACF,KAhBD,MAiBK;AACH;AACA,UAAI,aAAa,IAAI,IAAjB,IAAyB,aAAa,CAAC,IAAd,KAAuB,aAAa,CAAC,IAA9D,IAAsE,aAAa,CAAC,GAAd,KAAsB,SAAhG,EAA2G;AACzG,QAAA,aAAa,CAAC,GAAd,IAAqB,SAArB,CADyG,CAEzG;AACD,OAHD,MAIK;AACH,QAAA,aAAa,GAAG;AACd,UAAA,IAAI,EAAE,aAAa,CAAC,IADN;AAEd,UAAA,KAAK,EAAE,SAFO;AAGd,UAAA,GAAG,EAAE,SAAS,GAAG;AAHH,SAAhB;AAMA,QAAA,cAAc,CAAC,aAAD,EAAgB,UAAhB,EAA4B,QAA5B,EAAsC,CAAtC,CAAd;AACD;AACF;AACF;;AAED,MAAI,iBAAiB,GAAG,CAAxB,EAA2B;AACzB,IAAA,MAAM,CAAC,IAAP,CAAY,OAAO,YAAY,CAAC,IAAb,KAAsB,MAAtB,GAA+B,EAA/B,GAAqC,MAAM,YAAY,CAAC,IAAK,QAAQ,iBAAiB,iBAAzG;AACD;;AACD,SAAO,UAAP;AACD;;AAED,MAAM,wBAAwB,GAAG,OAAO,CAAC,GAAR,CAAY,kDAAZ,KAAmE,MAApG;;AAEA,SAAS,cAAT,CAAwB,SAAxB,EAA8C,UAA9C,EAA4E,QAA5E,EAA8F,KAA9F,EAA2G;AACzG,MAAI,wBAAwB,IAAI,UAAU,CAAC,MAAX,KAAsB,CAAtD,EAAyD;AACvD,UAAM,aAAa,GAAG,UAAU,CAAC,UAAU,CAAC,MAAX,GAAoB,CAArB,CAAhC;;AACA,QAAI,aAAa,CAAC,IAAd,KAAuB,SAAS,CAAC,IAAjC,IAAyC,SAAS,CAAC,KAAV,GAAkB,aAAa,CAAC,GAAzE,IAAgF,SAAS,CAAC,KAAV,GAAkB,aAAa,CAAC,KAApH,EAA2H;AACzH,YAAM,GAAG,GAAG,CAAC,aAAa,CAAC,KAAf,EAAsB,aAAa,CAAC,GAApC,EAAyC,SAAS,CAAC,KAAnD,EAA0D,SAAS,CAAC,GAApE,EAAyE,MAAzE,CAAgF,CAAC,CAAD,EAAI,CAAJ,KAAU,CAAC,GAAG,CAAJ,GAAQ,CAAR,GAAY,CAAtG,CAAZ;AACA,YAAM,IAAI,KAAJ,CAAU,2BAA2B,KAAK,eAAe,QAAQ,WAAW,aAAa,CAAC,SAAS,CAAC,IAAX,CAAgB,4CAA4C,QAAQ,MAAnJ,GAChB,QAAQ,aAAa,CAAC,KAAK,UAAU,aAAa,CAAC,GAAG,QAAQ,SAAS,CAAC,KAAK,UAAU,SAAS,CAAC,GAAG,IADpF,GAEhB,QAAQ,aAAa,CAAC,KAAd,GAAsB,GAAG,UAAU,aAAa,CAAC,GAAd,GAAoB,GAAG,QAAQ,SAAS,CAAC,KAAV,GAAkB,GAAG,UAAU,SAAS,CAAC,GAAV,GAAgB,GAAG,EAFtH,CAAN;AAID;AACF;;AACD,EAAA,UAAU,CAAC,IAAX,CAAgB,SAAhB;AACD,C,CAED;;;AACA,SAAS,gBAAT,CAA0B,IAA1B,EAA8C,UAA9C,EAAkE,MAAlE,EAAgF;AAC9E,QAAM,gBAAgB,GAAG,IAAI,GAAJ,EAAzB;AACA,QAAM,cAAc,GAAG,IAAI,GAAJ,EAAvB;AACA,MAAI,MAAM,GAAG,UAAb;AACA,QAAM,QAAQ,GAAG,MAAM,CAAC,KAAxB;;AACA,OAAK,IAAI,CAAC,GAAG,CAAb,EAAgB,CAAC,GAAG,IAAI,CAAC,SAAL,CAAe,MAAnC,EAA2C,CAAC,EAA5C,EAAgD;AAC9C,UAAM,QAAQ,GAAG,IAAI,CAAC,SAAL,CAAe,CAAf,CAAjB;AACA,UAAM,IAAI,GAAG,IAAI,CAAC,KAAL,CAAW,CAAX,CAAb;AAEA,UAAM,QAAQ,GAAG,cAAc,CAAC,GAAf,CAAmB,QAAnB,CAAjB;;AACA,QAAI,QAAQ,KAAK,SAAjB,EAA4B;AAC1B,MAAA,gBAAgB,CAAC,GAAjB,CAAqB,QAArB,EAA+B,MAA/B;AACA,MAAA,cAAc,CAAC,GAAf,CAAmB,QAAnB,EAA6B,IAA7B;AACD,KAHD,MAIK,IAAI,QAAQ,IAAI,IAAhB,EAAsB;AACzB,YAAM,eAAe,GAAG,QAAQ,KAAK,IAAb,GAAoB,aAApB,GAAoC,UAAU,QAAQ,gBAAgB,IAAI,GAAlG;AACA,MAAA,QAAQ,CAAC,GAAG,QAAQ,2BAA2B,eAAe,gGAAtD,CAAR;AACD;;AACD,IAAA,MAAM,IAAI,IAAV;AACD;;AACD,SAAO;AAAC,IAAA,gBAAD;AAAmB,IAAA,iBAAiB,EAAE;AAAtC,GAAP;AACD;;AAED,SAAS,iBAAT,CAA2B,IAA3B,EAAoD;AAClD,QAAM,MAAM,GAAG,IAAI,GAAJ,EAAf;;AACA,OAAK,MAAM,IAAX,IAAmB,IAAnB,EAAyB;AACvB,IAAA,MAAM,CAAC,GAAP,CAAW,IAAI,CAAC,IAAhB,EAAsB,IAAtB;AACD;;AACD,SAAO,MAAP;AACD,C","sourcesContent":["import { BlockMap, BlockMapFile } from \"builder-util-runtime/out/blockMapApi\"\nimport { Logger } from \"../main\"\n\nexport enum OperationKind {\n COPY, DOWNLOAD\n}\n\nexport interface Operation {\n kind: OperationKind\n\n // inclusive\n start: number\n // exclusive\n end: number\n\n // debug only\n // oldBlocks: Array<string> | null\n}\n\nexport function computeOperations(oldBlockMap: BlockMap, newBlockMap: BlockMap, logger: Logger): Array<Operation> {\n const nameToOldBlocks = buildBlockFileMap(oldBlockMap.files)\n const nameToNewBlocks = buildBlockFileMap(newBlockMap.files)\n\n let lastOperation: Operation | null = null\n\n // for now only one file is supported in block map\n const blockMapFile = newBlockMap.files[0]\n const operations: Array<Operation> = []\n const name = blockMapFile.name\n const oldEntry = nameToOldBlocks.get(name)\n if (oldEntry == null) {\n // new file (unrealistic case for now, because in any case both blockmap contain the only file named as \"file\")\n throw new Error(`no file ${name} in old blockmap`)\n }\n\n const newFile = nameToNewBlocks.get(name)!!\n let changedBlockCount = 0\n\n const {checksumToOffset: checksumToOldOffset, checksumToOldSize} = buildChecksumMap(nameToOldBlocks.get(name)!!, oldEntry.offset, logger)\n\n let newOffset = blockMapFile.offset\n for (let i = 0; i < newFile.checksums.length; newOffset += newFile.sizes[i], i++) {\n const blockSize = newFile.sizes[i]\n const checksum = newFile.checksums[i]\n let oldOffset = checksumToOldOffset.get(checksum)\n if (oldOffset != null && checksumToOldSize.get(checksum) !== blockSize) {\n logger.warn(`Checksum (\"${checksum}\") matches, but size differs (old: ${checksumToOldSize.get(checksum)}, new: ${blockSize})`)\n oldOffset = undefined\n }\n\n if (oldOffset === undefined) {\n // download data from new file\n changedBlockCount++\n\n if (lastOperation != null && lastOperation.kind === OperationKind.DOWNLOAD && lastOperation.end === newOffset) {\n lastOperation.end += blockSize\n }\n else {\n lastOperation = {\n kind: OperationKind.DOWNLOAD,\n start: newOffset,\n end: newOffset + blockSize,\n // oldBlocks: null,\n }\n validateAndAdd(lastOperation, operations, checksum, i)\n }\n }\n else {\n // reuse data from old file\n if (lastOperation != null && lastOperation.kind === OperationKind.COPY && lastOperation.end === oldOffset) {\n lastOperation.end += blockSize\n // lastOperation.oldBlocks!!.push(checksum)\n }\n else {\n lastOperation = {\n kind: OperationKind.COPY,\n start: oldOffset,\n end: oldOffset + blockSize,\n // oldBlocks: [checksum]\n }\n validateAndAdd(lastOperation, operations, checksum, i)\n }\n }\n }\n\n if (changedBlockCount > 0) {\n logger.info(`File${blockMapFile.name === \"file\" ? \"\" : (\" \" + blockMapFile.name)} has ${changedBlockCount} changed blocks`)\n }\n return operations\n}\n\nconst isValidateOperationRange = process.env.DIFFERENTIAL_DOWNLOAD_PLAN_BUILDER_VALIDATE_RANGES === \"true\"\n\nfunction validateAndAdd(operation: Operation, operations: Array<Operation>, checksum: string, index: number): void {\n if (isValidateOperationRange && operations.length !== 0) {\n const lastOperation = operations[operations.length - 1]\n if (lastOperation.kind === operation.kind && operation.start < lastOperation.end && operation.start > lastOperation.start) {\n const min = [lastOperation.start, lastOperation.end, operation.start, operation.end].reduce((p, v) => p < v ? p : v)\n throw new Error(`operation (block index: ${index}, checksum: ${checksum}, kind: ${OperationKind[operation.kind]}) overlaps previous operation (checksum: ${checksum}):\\n` +\n `abs: ${lastOperation.start} until ${lastOperation.end} and ${operation.start} until ${operation.end}\\n` +\n `rel: ${lastOperation.start - min} until ${lastOperation.end - min} and ${operation.start - min} until ${operation.end - min}`\n )\n }\n }\n operations.push(operation)\n}\n\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\nfunction buildChecksumMap(file: BlockMapFile, fileOffset: number, logger: Logger) {\n const checksumToOffset = new Map<string, number>()\n const checksumToSize = new Map<string, number>()\n let offset = fileOffset\n const debugLog = logger.debug\n for (let i = 0; i < file.checksums.length; i++) {\n const checksum = file.checksums[i]\n const size = file.sizes[i]\n\n const existing = checksumToSize.get(checksum)\n if (existing === undefined) {\n checksumToOffset.set(checksum, offset)\n checksumToSize.set(checksum, size)\n }\n else if (debugLog != null) {\n const sizeExplanation = existing === size ? \"(same size)\" : `(size: ${existing}, this size: ${size})`\n debugLog(`${checksum} duplicated in blockmap ${sizeExplanation}, it doesn't lead to broken differential downloader, just corresponding block will be skipped)`)\n }\n offset += size\n }\n return {checksumToOffset, checksumToOldSize: checksumToSize}\n}\n\nfunction buildBlockFileMap(list: Array<BlockMapFile>): Map<string, BlockMapFile> {\n const result = new Map<string, BlockMapFile>()\n for (const item of list) {\n result.set(item.name, item)\n }\n return result\n}\n"],"sourceRoot":""}
1
+ {"version":3,"file":"downloadPlanBuilder.js","sourceRoot":"","sources":["../../src/differentialDownloader/downloadPlanBuilder.ts"],"names":[],"mappings":"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","sourcesContent":["import { BlockMap, BlockMapFile } from \"builder-util-runtime/out/blockMapApi\"\nimport { Logger } from \"../main\"\n\nexport enum OperationKind {\n COPY,\n DOWNLOAD,\n}\n\nexport interface Operation {\n kind: OperationKind\n\n // inclusive\n start: number\n // exclusive\n end: number\n\n // debug only\n // oldBlocks: Array<string> | null\n}\n\nexport function computeOperations(oldBlockMap: BlockMap, newBlockMap: BlockMap, logger: Logger): Array<Operation> {\n const nameToOldBlocks = buildBlockFileMap(oldBlockMap.files)\n const nameToNewBlocks = buildBlockFileMap(newBlockMap.files)\n\n let lastOperation: Operation | null = null\n\n // for now only one file is supported in block map\n const blockMapFile = newBlockMap.files[0]\n const operations: Array<Operation> = []\n const name = blockMapFile.name\n const oldEntry = nameToOldBlocks.get(name)\n if (oldEntry == null) {\n // new file (unrealistic case for now, because in any case both blockmap contain the only file named as \"file\")\n throw new Error(`no file ${name} in old blockmap`)\n }\n\n const newFile = nameToNewBlocks.get(name)!\n let changedBlockCount = 0\n\n const { checksumToOffset: checksumToOldOffset, checksumToOldSize } = buildChecksumMap(nameToOldBlocks.get(name)!, oldEntry.offset, logger)\n\n let newOffset = blockMapFile.offset\n for (let i = 0; i < newFile.checksums.length; newOffset += newFile.sizes[i], i++) {\n const blockSize = newFile.sizes[i]\n const checksum = newFile.checksums[i]\n let oldOffset = checksumToOldOffset.get(checksum)\n if (oldOffset != null && checksumToOldSize.get(checksum) !== blockSize) {\n logger.warn(`Checksum (\"${checksum}\") matches, but size differs (old: ${checksumToOldSize.get(checksum)}, new: ${blockSize})`)\n oldOffset = undefined\n }\n\n if (oldOffset === undefined) {\n // download data from new file\n changedBlockCount++\n\n if (lastOperation != null && lastOperation.kind === OperationKind.DOWNLOAD && lastOperation.end === newOffset) {\n lastOperation.end += blockSize\n } else {\n lastOperation = {\n kind: OperationKind.DOWNLOAD,\n start: newOffset,\n end: newOffset + blockSize,\n // oldBlocks: null,\n }\n validateAndAdd(lastOperation, operations, checksum, i)\n }\n } else {\n // reuse data from old file\n if (lastOperation != null && lastOperation.kind === OperationKind.COPY && lastOperation.end === oldOffset) {\n lastOperation.end += blockSize\n // lastOperation.oldBlocks!!.push(checksum)\n } else {\n lastOperation = {\n kind: OperationKind.COPY,\n start: oldOffset,\n end: oldOffset + blockSize,\n // oldBlocks: [checksum]\n }\n validateAndAdd(lastOperation, operations, checksum, i)\n }\n }\n }\n\n if (changedBlockCount > 0) {\n logger.info(`File${blockMapFile.name === \"file\" ? \"\" : \" \" + blockMapFile.name} has ${changedBlockCount} changed blocks`)\n }\n return operations\n}\n\nconst isValidateOperationRange = process.env.DIFFERENTIAL_DOWNLOAD_PLAN_BUILDER_VALIDATE_RANGES === \"true\"\n\nfunction validateAndAdd(operation: Operation, operations: Array<Operation>, checksum: string, index: number): void {\n if (isValidateOperationRange && operations.length !== 0) {\n const lastOperation = operations[operations.length - 1]\n if (lastOperation.kind === operation.kind && operation.start < lastOperation.end && operation.start > lastOperation.start) {\n const min = [lastOperation.start, lastOperation.end, operation.start, operation.end].reduce((p, v) => (p < v ? p : v))\n throw new Error(\n `operation (block index: ${index}, checksum: ${checksum}, kind: ${OperationKind[operation.kind]}) overlaps previous operation (checksum: ${checksum}):\\n` +\n `abs: ${lastOperation.start} until ${lastOperation.end} and ${operation.start} until ${operation.end}\\n` +\n `rel: ${lastOperation.start - min} until ${lastOperation.end - min} and ${operation.start - min} until ${operation.end - min}`\n )\n }\n }\n operations.push(operation)\n}\n\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\nfunction buildChecksumMap(file: BlockMapFile, fileOffset: number, logger: Logger) {\n const checksumToOffset = new Map<string, number>()\n const checksumToSize = new Map<string, number>()\n let offset = fileOffset\n for (let i = 0; i < file.checksums.length; i++) {\n const checksum = file.checksums[i]\n const size = file.sizes[i]\n\n const existing = checksumToSize.get(checksum)\n if (existing === undefined) {\n checksumToOffset.set(checksum, offset)\n checksumToSize.set(checksum, size)\n } else if (logger.debug != null) {\n const sizeExplanation = existing === size ? \"(same size)\" : `(size: ${existing}, this size: ${size})`\n logger.debug(`${checksum} duplicated in blockmap ${sizeExplanation}, it doesn't lead to broken differential downloader, just corresponding block will be skipped)`)\n }\n offset += size\n }\n return { checksumToOffset, checksumToOldSize: checksumToSize }\n}\n\nfunction buildBlockFileMap(list: Array<BlockMapFile>): Map<string, BlockMapFile> {\n const result = new Map<string, BlockMapFile>()\n for (const item of list) {\n result.set(item.name, item)\n }\n return result\n}\n"]}