core-3nweb-client-lib 0.43.9 → 0.43.12

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 (58) hide show
  1. package/build/api-defs/files.d.ts +32 -8
  2. package/build/api-defs/web3n.d.ts +2 -0
  3. package/build/core/asmail/inbox/index.js +1 -1
  4. package/build/core/asmail/inbox/msg-downloader.d.ts +2 -12
  5. package/build/core/asmail/inbox/msg-downloader.js +13 -46
  6. package/build/core/storage/synced/downloader.d.ts +6 -15
  7. package/build/core/storage/synced/downloader.js +25 -48
  8. package/build/core/storage/synced/obj-files.d.ts +4 -2
  9. package/build/core/storage/synced/obj-files.js +7 -7
  10. package/build/core/storage/synced/storage.d.ts +4 -2
  11. package/build/core/storage/synced/storage.js +2 -2
  12. package/build/core/storage/synced/upsyncer.d.ts +2 -4
  13. package/build/core/storage/synced/upsyncer.js +19 -13
  14. package/build/core-ipc/file.d.ts +10 -0
  15. package/build/core-ipc/file.js +23 -13
  16. package/build/core-ipc/fs.js +15 -8
  17. package/build/lib-client/3nstorage/storage-owner.js +36 -29
  18. package/build/lib-client/3nweb-signup.js +7 -7
  19. package/build/lib-client/asmail/recipient.js +14 -11
  20. package/build/lib-client/asmail/sender.js +24 -25
  21. package/build/lib-client/asmail/service-config.js +3 -6
  22. package/build/lib-client/cryptor/cryptor-wasm.js +1 -1
  23. package/build/lib-client/cryptor/cryptor.wasm +0 -0
  24. package/build/lib-client/fs-utils/files.js +4 -4
  25. package/build/lib-client/mailer-id/login.js +7 -7
  26. package/build/lib-client/mailer-id/provisioner.js +9 -7
  27. package/build/lib-client/objs-on-disk/file-writing-proc.d.ts +1 -1
  28. package/build/lib-client/objs-on-disk/obj-on-disk.d.ts +51 -3
  29. package/build/lib-client/objs-on-disk/obj-on-disk.js +414 -34
  30. package/build/lib-client/request-utils.d.ts +0 -7
  31. package/build/lib-client/request-utils.js +16 -11
  32. package/build/lib-client/service-locator.js +11 -8
  33. package/build/lib-client/user-with-mid-session.js +2 -6
  34. package/build/lib-client/user-with-pkl-session.js +25 -24
  35. package/build/lib-client/xsp-fs/common.d.ts +8 -3
  36. package/build/lib-client/xsp-fs/common.js +1 -1
  37. package/build/lib-client/xsp-fs/file.d.ts +3 -1
  38. package/build/lib-client/xsp-fs/file.js +4 -4
  39. package/build/lib-client/xsp-fs/folder-node.d.ts +1 -1
  40. package/build/lib-client/xsp-fs/folder-node.js +4 -4
  41. package/build/lib-client/xsp-fs/fs.d.ts +3 -1
  42. package/build/lib-client/xsp-fs/fs.js +4 -4
  43. package/build/lib-client/xsp-fs/node-in-fs.d.ts +6 -4
  44. package/build/lib-client/xsp-fs/node-in-fs.js +14 -9
  45. package/build/lib-common/buffer-utils.js +4 -1
  46. package/build/lib-common/exceptions/http.d.ts +11 -1
  47. package/build/lib-common/exceptions/http.js +10 -2
  48. package/build/lib-common/objs-on-disk/utils.d.ts +1 -1
  49. package/build/lib-common/processes/labelled-exec-pools.d.ts +1 -1
  50. package/build/lib-common/processes/labelled-exec-pools.js +8 -2
  51. package/build/protos/asmail.proto.js +545 -116
  52. package/build/protos/file.proto.js +485 -56
  53. package/build/protos/fs.proto.js +545 -116
  54. package/package.json +1 -1
  55. package/protos/file.proto +8 -2
  56. package/protos/fs.proto +3 -3
  57. /package/build/lib-common/objs-on-disk/{obj-file.d.ts → obj-version-file.d.ts} +0 -0
  58. /package/build/lib-common/objs-on-disk/{obj-file.js → obj-version-file.js} +0 -0
@@ -412,7 +412,7 @@ declare namespace web3n.files {
412
412
  */
413
413
  getByteSource(): Promise<FileByteSource>;
414
414
 
415
- watch(observer: Observer<FileEvent|RemoteEvent|UploadEvent>): () => void;
415
+ watch(observer: Observer<FileEvent|RemoteEvent|UploadEvent|DownloadEvent>): () => void;
416
416
 
417
417
  }
418
418
 
@@ -638,7 +638,7 @@ declare namespace web3n.files {
638
638
  * This downloads bytes onto disk, skipping decryption, as file content isn't read here.
639
639
  * @param version
640
640
  */
641
- download(version: number): Promise<void>;
641
+ startDownload(version: number): Promise<{ downloadTaskId: number; }|undefined>;
642
642
 
643
643
  /**
644
644
  * Adopts remote version.
@@ -665,7 +665,7 @@ declare namespace web3n.files {
665
665
  * Undefined is returned when upload is not needed, e.g. version is already synced.
666
666
  * Upload version and upload task id are returned together with an indicator of whether
667
667
  * this call has started upload, or it has already been going on.
668
- * Upload task id can be used to watch upload process.
668
+ * Upload task id can be used to filter watched events.
669
669
  * @param opts
670
670
  */
671
671
  startUpload(
@@ -674,6 +674,7 @@ declare namespace web3n.files {
674
674
 
675
675
  /**
676
676
  * Upload in conflicting and behind state of sync requires explicit upload version.
677
+ * This upload will not be generating upload events.
677
678
  * @param opts
678
679
  */
679
680
  upload(opts?: OptionsToUploadLocal): Promise<number|undefined>;
@@ -763,16 +764,16 @@ declare namespace web3n.files {
763
764
  readLink(path: string): Promise<SymLink>;
764
765
 
765
766
  watchFolder(
766
- path: string, observer: Observer<FolderEvent|RemoteEvent|UploadEvent>
767
+ path: string, observer: Observer<FolderEvent|RemoteEvent|UploadEvent|DownloadEvent>
767
768
  ): () => void;
768
769
 
769
770
  watchFile(
770
- path: string, observer: Observer<FileEvent|RemoteEvent|UploadEvent>
771
+ path: string, observer: Observer<FileEvent|RemoteEvent|UploadEvent|DownloadEvent>
771
772
  ): () => void;
772
773
 
773
774
  watchTree(
774
775
  path: string, depth: number|undefined,
775
- observer: Observer<FolderEvent|FileEvent|RemoteEvent|UploadEvent>
776
+ observer: Observer<FolderEvent|FileEvent|RemoteEvent|UploadEvent|DownloadEvent>
776
777
  ): () => void;
777
778
 
778
779
  close(): Promise<void>;
@@ -1288,7 +1289,7 @@ declare namespace web3n.files {
1288
1289
  * @param path
1289
1290
  * @param version
1290
1291
  */
1291
- download(path: string, version: number): Promise<void>;
1292
+ startDownload(path: string, version: number): Promise<{ downloadTaskId: number; }|undefined>;
1292
1293
 
1293
1294
  /**
1294
1295
  * Adopts remote version of fs object at given path.
@@ -1340,7 +1341,7 @@ declare namespace web3n.files {
1340
1341
  * Undefined is returned when upload is not needed, e.g. version is already synced.
1341
1342
  * Upload version and upload task id are returned together with an indicator of whether
1342
1343
  * this call has started upload, or it has already been going on.
1343
- * Upload task id can be used to watch upload process.
1344
+ * Upload task id can be used to filter watched events.
1344
1345
  * @param path
1345
1346
  * @param opts
1346
1347
  */
@@ -1350,6 +1351,7 @@ declare namespace web3n.files {
1350
1351
 
1351
1352
  /**
1352
1353
  * Upload in conflicting and behind state of sync requires explicit upload version.
1354
+ * This upload will not be generating upload events.
1353
1355
  * @param path
1354
1356
  * @param opts
1355
1357
  */
@@ -1470,4 +1472,26 @@ declare namespace web3n.files {
1470
1472
  type: 'upload-done';
1471
1473
  }
1472
1474
 
1475
+ type DownloadEvent = DownloadStartEvent | DownloadProgressEvent | DownloadDoneEvent;
1476
+
1477
+ interface DownloadEventBase extends FSEvent {
1478
+ downloadTaskId: number;
1479
+ version: number;
1480
+ }
1481
+
1482
+ interface DownloadStartEvent extends DownloadEventBase {
1483
+ type: 'download-started';
1484
+ totalBytesToDownload: number;
1485
+ }
1486
+
1487
+ interface DownloadDoneEvent extends DownloadEventBase {
1488
+ type: 'download-done';
1489
+ }
1490
+
1491
+ interface DownloadProgressEvent extends DownloadEventBase {
1492
+ type: 'download-progress';
1493
+ totalBytesToDownload: number;
1494
+ bytesLeftToDownload: number;
1495
+ }
1496
+
1473
1497
  }
@@ -56,6 +56,8 @@ declare namespace web3n {
56
56
  interface HTTPException extends HTTPErrorDetails {
57
57
  type: 'http-request';
58
58
  status: number;
59
+ malformedResponse?: true;
60
+ unexpectedStatus?: true;
59
61
  }
60
62
 
61
63
  interface ServLocException extends RuntimeException {
@@ -110,7 +110,7 @@ class InboxOnServer {
110
110
  return msgOnDisk;
111
111
  }
112
112
  const meta = await this.downloader.getMsgMeta(msgId);
113
- return this.cache.addMsg(msgId, meta);
113
+ return await this.cache.addMsg(msgId, meta);
114
114
  }
115
115
  async startCachingAndAddKeyToIndex(msgId) {
116
116
  const msgOnDisk = await this.msgFromDiskOrDownload(msgId);
@@ -1,20 +1,10 @@
1
1
  import { MailRecipient } from "../../../lib-client/asmail/recipient";
2
2
  import { ObjDownloader } from "../../../lib-client/objs-on-disk/obj-on-disk";
3
3
  import { MsgMeta } from "../../../lib-common/service-api/asmail/retrieval";
4
- /**
5
- * Downloader is responsible for getting mail objects from server and placing
6
- * bytes into cache.
7
- */
8
4
  export declare class MsgDownloader {
9
- private msgReceiver;
10
- /**
11
- * Per-object chained downloads.
12
- * When it comes to the download start, if chain exists, it means that
13
- * process has already started.
14
- */
15
- private downloadProcs;
5
+ private readonly msgReceiver;
6
+ private readonly runner;
16
7
  constructor(msgReceiver: MailRecipient);
17
- private sync;
18
8
  getMsgMeta(msgId: string): Promise<MsgMeta>;
19
9
  getObjDownloader(msgId: string): ObjDownloader;
20
10
  private getLayoutWithHeaderAndFirstSegs;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /*
3
- Copyright (C) 2016 - 2019 3NSoft Inc.
3
+ Copyright (C) 2016 - 2019, 2025 3NSoft Inc.
4
4
 
5
5
  This program is free software: you can redistribute it and/or modify it under
6
6
  the terms of the GNU General Public License as published by the Free Software
@@ -13,72 +13,39 @@
13
13
  See the GNU General Public License for more details.
14
14
 
15
15
  You should have received a copy of the GNU General Public License along with
16
- this program. If not, see <http://www.gnu.org/licenses/>. */
16
+ this program. If not, see <http://www.gnu.org/licenses/>.
17
+ */
17
18
  Object.defineProperty(exports, "__esModule", { value: true });
18
19
  exports.MsgDownloader = void 0;
19
- const synced_1 = require("../../../lib-common/processes/synced");
20
- const buffer_utils_1 = require("../../../lib-common/buffer-utils");
20
+ const obj_on_disk_1 = require("../../../lib-client/objs-on-disk/obj-on-disk");
21
21
  const MAX_GETTING_CHUNK = 512 * 1024;
22
22
  const DOWNLOAD_START_CHUNK = 128 * 1024;
23
- /**
24
- * Downloader is responsible for getting mail objects from server and placing
25
- * bytes into cache.
26
- */
27
23
  class MsgDownloader {
28
24
  constructor(msgReceiver) {
29
25
  this.msgReceiver = msgReceiver;
30
- /**
31
- * Per-object chained downloads.
32
- * When it comes to the download start, if chain exists, it means that
33
- * process has already started.
34
- */
35
- this.downloadProcs = new synced_1.NamedProcs();
26
+ this.runner = new obj_on_disk_1.DownloadsRunner();
36
27
  Object.freeze(this);
37
28
  }
38
- async sync(msgId, objId, action) {
39
- const id = `${msgId}/${objId}`;
40
- return this.downloadProcs.startOrChain(id, action);
41
- }
42
29
  getMsgMeta(msgId) {
43
- return this.sync(msgId, null, () => this.msgReceiver.getMsgMeta(msgId));
30
+ return this.msgReceiver.getMsgMeta(msgId);
44
31
  }
45
32
  getObjDownloader(msgId) {
46
33
  return {
47
- getLayoutWithHeaderAndFirstSegs: objId => this.getLayoutWithHeaderAndFirstSegs(msgId, objId),
48
- getSegs: (objId, v, start, end) => this.getSegs(msgId, objId, start, end)
34
+ getLayoutWithHeaderAndFirstSegs: (objId, v) => this.getLayoutWithHeaderAndFirstSegs(msgId, objId),
35
+ getSegs: (objId, v, start, end) => this.getSegs(msgId, objId, start, end),
36
+ splitSegsDownloads: (start, end) => (0, obj_on_disk_1.splitSegsDownloads)(start, end, MAX_GETTING_CHUNK),
37
+ schedule: this.runner.schedule.bind(this.runner)
49
38
  };
50
39
  }
51
40
  async getLayoutWithHeaderAndFirstSegs(msgId, objId) {
52
- if (!objId) {
53
- throw new Error(`Message object cannot be null`);
54
- }
55
- const { header, segsChunk, segsTotalLen } = await this.sync(msgId, objId, () => this.msgReceiver.getObj(msgId, objId, DOWNLOAD_START_CHUNK));
41
+ const { header, segsChunk, segsTotalLen } = await this.msgReceiver.getObj(msgId, objId, DOWNLOAD_START_CHUNK);
56
42
  const layout = {
57
43
  sections: [{ src: 'new', ofs: 0, len: segsTotalLen }]
58
44
  };
59
45
  return { header, segs: segsChunk, layout };
60
46
  }
61
- async getSegs(msgId, objId, start, end) {
62
- if (!objId) {
63
- throw new Error(`Message object cannot have null id`);
64
- }
65
- return this.sync(msgId, objId, async () => {
66
- if ((end - start) < MAX_GETTING_CHUNK) {
67
- const allBytes = await this.msgReceiver.getObjSegs(msgId, objId, start, end);
68
- return allBytes;
69
- }
70
- else {
71
- const chunks = [];
72
- let ofs = start;
73
- while (ofs < end) {
74
- const len = Math.min(end - ofs, MAX_GETTING_CHUNK);
75
- const chunk = await this.msgReceiver.getObjSegs(msgId, objId, ofs, ofs + len);
76
- chunks.push(chunk);
77
- ofs += chunk.length;
78
- }
79
- return (0, buffer_utils_1.joinByteArrs)(chunks);
80
- }
81
- });
47
+ getSegs(msgId, objId, start, end) {
48
+ return this.msgReceiver.getObjSegs(msgId, objId, start, end);
82
49
  }
83
50
  }
84
51
  exports.MsgDownloader = MsgDownloader;
@@ -1,25 +1,16 @@
1
1
  import { StorageOwner } from '../../../lib-client/3nstorage/storage-owner';
2
2
  import { ObjId } from '../../../lib-client/xsp-fs/common';
3
- import { ObjDownloader, InitDownloadParts } from '../../../lib-client/objs-on-disk/obj-on-disk';
4
- import { Layout } from 'xsp-files';
3
+ import { ObjDownloader, InitDownloadParts, Section, Download } from '../../../lib-client/objs-on-disk/obj-on-disk';
5
4
  export declare class Downloader implements ObjDownloader {
6
- private remoteStorage;
7
- /**
8
- * Per-object chained downloads.
9
- * When it comes to the download start, if chain exists, it means that
10
- * process has already started.
11
- */
12
- private downloadProcs;
5
+ private readonly remoteStorage;
6
+ private readonly runner;
13
7
  constructor(remoteStorage: StorageOwner);
14
- private sync;
15
- getLayoutWithHeaderAndFirstSegs(objId: ObjId, version: number): Promise<{
16
- layout: Layout;
17
- header: Uint8Array;
18
- segs?: Uint8Array;
19
- }>;
8
+ getLayoutWithHeaderAndFirstSegs(objId: ObjId, version: number): Promise<InitDownloadParts>;
9
+ schedule(download: Download): void;
20
10
  getSegs(objId: ObjId, version: number, start: number, end: number): Promise<Uint8Array>;
21
11
  getCurrentObjVersion(objId: ObjId): Promise<{
22
12
  version: number;
23
13
  parts: InitDownloadParts;
24
14
  }>;
15
+ splitSegsDownloads(start: number, end: number): Section[];
25
16
  }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /*
3
- Copyright (C) 2016 - 2019 3NSoft Inc.
3
+ Copyright (C) 2016 - 2019, 2025 3NSoft Inc.
4
4
 
5
5
  This program is free software: you can redistribute it and/or modify it under
6
6
  the terms of the GNU General Public License as published by the Free Software
@@ -17,65 +17,42 @@
17
17
  */
18
18
  Object.defineProperty(exports, "__esModule", { value: true });
19
19
  exports.Downloader = void 0;
20
- const synced_1 = require("../../../lib-common/processes/synced");
21
- const buffer_utils_1 = require("../../../lib-common/buffer-utils");
20
+ const obj_on_disk_1 = require("../../../lib-client/objs-on-disk/obj-on-disk");
22
21
  const MAX_GETTING_CHUNK = 512 * 1024;
23
22
  const DOWNLOAD_START_CHUNK = 128 * 1024;
24
23
  class Downloader {
25
24
  constructor(remoteStorage) {
26
25
  this.remoteStorage = remoteStorage;
27
- /**
28
- * Per-object chained downloads.
29
- * When it comes to the download start, if chain exists, it means that
30
- * process has already started.
31
- */
32
- this.downloadProcs = new synced_1.NamedProcs();
26
+ this.runner = new obj_on_disk_1.DownloadsRunner();
33
27
  Object.seal(this);
34
28
  }
35
- async sync(objId, version, action) {
36
- const id = `${objId}/${version}`;
37
- return this.downloadProcs.startOrChain(id, action);
29
+ async getLayoutWithHeaderAndFirstSegs(objId, version) {
30
+ const { header, segsTotalLen, version: currentVersion, segsChunk } = await this.remoteStorage.getCurrentObj(objId, DOWNLOAD_START_CHUNK);
31
+ // XXX this gets current version, but it will have to change to getting
32
+ // just version. It will be seen, if version's state needs passing.
33
+ if (currentVersion !== version) {
34
+ throw new Error(`Current version on server is ${currentVersion} while request was for ${version}`);
35
+ }
36
+ const layout = {
37
+ sections: [{ src: 'new', ofs: 0, len: segsTotalLen }]
38
+ };
39
+ return { header, segs: segsChunk, layout };
38
40
  }
39
- getLayoutWithHeaderAndFirstSegs(objId, version) {
40
- return this.sync(objId, version, async () => {
41
- // XXX this gets current version, but it will have to change to getting
42
- // just version. It will be seen, if version's state needs passing.
43
- const { header, segsTotalLen, version, segsChunk } = await this.remoteStorage.getCurrentObj(objId, DOWNLOAD_START_CHUNK);
44
- const layout = {
45
- sections: [{ src: 'new', ofs: 0, len: segsTotalLen }]
46
- };
47
- return { header, segs: segsChunk, layout };
48
- });
41
+ schedule(download) {
42
+ this.runner.schedule(download);
49
43
  }
50
44
  getSegs(objId, version, start, end) {
51
- // XXX this gets current version, but it will have to change to getting
52
- // just version. It will be seen, if version's state needs passing.
53
- return this.sync(objId, version, async () => {
54
- if ((end - start) < MAX_GETTING_CHUNK) {
55
- const allBytes = await this.remoteStorage.getCurrentObjSegs(objId, version, start, end);
56
- return allBytes;
57
- }
58
- else {
59
- const chunks = [];
60
- let ofs = start;
61
- while (ofs < end) {
62
- const len = Math.min(end - ofs, MAX_GETTING_CHUNK);
63
- const chunk = await this.remoteStorage.getCurrentObjSegs(objId, version, ofs, ofs + len);
64
- chunks.push(chunk);
65
- ofs += chunk.length;
66
- }
67
- return (0, buffer_utils_1.joinByteArrs)(chunks);
68
- }
69
- });
45
+ return this.remoteStorage.getCurrentObjSegs(objId, version, start, end);
70
46
  }
71
47
  async getCurrentObjVersion(objId) {
72
- return await this.sync(objId, -1, async () => {
73
- const { header, segsTotalLen, version, segsChunk } = await this.remoteStorage.getCurrentObj(objId, DOWNLOAD_START_CHUNK);
74
- const layout = {
75
- sections: [{ src: 'new', ofs: 0, len: segsTotalLen }]
76
- };
77
- return { version, parts: { header, segs: segsChunk, layout } };
78
- });
48
+ const { header, segsTotalLen, version, segsChunk: segs } = await this.remoteStorage.getCurrentObj(objId, DOWNLOAD_START_CHUNK);
49
+ const layout = {
50
+ sections: [{ src: 'new', ofs: 0, len: segsTotalLen }]
51
+ };
52
+ return { version, parts: { header, segs, layout } };
53
+ }
54
+ splitSegsDownloads(start, end) {
55
+ return (0, obj_on_disk_1.splitSegsDownloads)(start, end, MAX_GETTING_CHUNK);
79
56
  }
80
57
  }
81
58
  exports.Downloader = Downloader;
@@ -1,5 +1,5 @@
1
1
  import { Observable } from 'rxjs';
2
- import { ObjId, SyncedObjStatus } from '../../../lib-client/xsp-fs/common';
2
+ import { DownloadEventSink, ObjId, SyncedObjStatus } from '../../../lib-client/xsp-fs/common';
3
3
  import { InitDownloadParts } from '../../../lib-client/objs-on-disk/obj-on-disk';
4
4
  import { ObjSource, Subscribe } from 'xsp-files';
5
5
  import { Downloader } from './downloader';
@@ -91,5 +91,7 @@ export declare class SyncedObj {
91
91
  recordRemovalUploadAndGC(): Promise<void>;
92
92
  isRemoteVersionOnDisk(version: number): Promise<'complete' | 'partial' | 'none'>;
93
93
  getNumOfBytesNeedingDownload(version: number): Promise<number | 'unknown'>;
94
- downloadRemoteVersion(version: number): Promise<void>;
94
+ startDownloadProcess(version: number, eventSink: DownloadEventSink): Promise<{
95
+ downloadTaskId: number;
96
+ } | undefined>;
95
97
  }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /*
3
- Copyright (C) 2016 - 2020, 2022 3NSoft Inc.
3
+ Copyright (C) 2016 - 2020, 2022, 2025 3NSoft Inc.
4
4
 
5
5
  This program is free software: you can redistribute it and/or modify it under
6
6
  the terms of the GNU General Public License as published by the Free Software
@@ -128,9 +128,8 @@ class ObjFiles {
128
128
  // Should it be a pattern: version not in status -> get info first.
129
129
  async makeByDownloadingCurrentVersion(objId) {
130
130
  // initial download implicitly checks existence of obj on server
131
- const download = await this.downloader.getCurrentObjVersion(objId);
132
- const obj = await this.makeObj(objId, download);
133
- return obj;
131
+ const initDownload = await this.downloader.getCurrentObjVersion(objId);
132
+ return await this.makeObj(objId, initDownload);
134
133
  }
135
134
  async saveFirstVersion(objId, encSub) {
136
135
  const newObj = await this.makeObj(objId);
@@ -406,7 +405,7 @@ class SyncedObj {
406
405
  return 'none';
407
406
  }
408
407
  const objVer = await this.instanceOfRemoteObjVer(version);
409
- return (objVer.doesFileNeedDownload() ? 'complete' : 'partial');
408
+ return (objVer.doesFileNeedDownload() ? 'partial' : 'complete');
410
409
  }
411
410
  async getNumOfBytesNeedingDownload(version) {
412
411
  if (!this.status.isAmongRemote(version)) {
@@ -424,9 +423,10 @@ class SyncedObj {
424
423
  const objVer = await this.instanceOfRemoteObjVer(version);
425
424
  return objVer.numOfBytesNeedingDownload();
426
425
  }
427
- async downloadRemoteVersion(version) {
426
+ async startDownloadProcess(version, eventSink) {
428
427
  const objVer = await this.instanceOfRemoteObjVer(version);
429
- await objVer.downloadMissingSections();
428
+ const downloadTaskId = objVer.startDownloadInBackground(eventSink);
429
+ return (downloadTaskId ? { downloadTaskId } : undefined);
430
430
  }
431
431
  }
432
432
  exports.SyncedObj = SyncedObj;
@@ -1,5 +1,5 @@
1
1
  import { IGetMailerIdSigner } from '../../../lib-client/user-with-mid-session';
2
- import { SyncedStorage as ISyncedStorage, NodesContainer, Storage as IStorage, StorageGetter, ObjId, NodeEvent, SyncedObjStatus } from '../../../lib-client/xsp-fs/common';
2
+ import { SyncedStorage as ISyncedStorage, NodesContainer, Storage as IStorage, StorageGetter, ObjId, NodeEvent, SyncedObjStatus, DownloadEventSink } from '../../../lib-client/xsp-fs/common';
3
3
  import { ScryptGenParams } from '../../../lib-client/key-derivation';
4
4
  import { LogError } from '../../../lib-client/logging/log-to-file';
5
5
  import { AsyncSBoxCryptor, Subscribe, ObjSource } from 'xsp-files';
@@ -39,7 +39,9 @@ export declare class SyncedStore implements ISyncedStorage {
39
39
  adoptRemote(objId: ObjId, opts: OptionsToAdopteRemote | undefined): Promise<number | undefined>;
40
40
  updateStatusInfo(objId: ObjId): Promise<SyncStatus>;
41
41
  isRemoteVersionOnDisk(objId: ObjId, version: number): Promise<'complete' | 'partial' | 'none'>;
42
- download(objId: ObjId, version: number): Promise<void>;
42
+ startDownload(objId: ObjId, version: number, eventSink: DownloadEventSink): Promise<{
43
+ downloadTaskId: number;
44
+ } | undefined>;
43
45
  startUpload(objId: ObjId, localVersion: number, uploadVersion: number, uploadHeader: UploadHeaderChange | undefined, createOnRemote: boolean, eventSink: (event: UploadEvent) => void): Promise<{
44
46
  uploadTaskId: number;
45
47
  completion: Promise<void>;
@@ -118,9 +118,9 @@ class SyncedStore {
118
118
  const obj = await this.getObjOrThrow(objId, true);
119
119
  return obj.isRemoteVersionOnDisk(version);
120
120
  }
121
- async download(objId, version) {
121
+ async startDownload(objId, version, eventSink) {
122
122
  const obj = await this.getObjOrThrow(objId, true);
123
- return obj.downloadRemoteVersion(version);
123
+ return obj.startDownloadProcess(version, eventSink);
124
124
  }
125
125
  async startUpload(objId, localVersion, uploadVersion, uploadHeader, createOnRemote, eventSink) {
126
126
  const obj = await this.getObjOrThrow(objId, true);
@@ -4,8 +4,7 @@ import { MonoTypeOperatorFunction } from "rxjs";
4
4
  import { FileWrite } from "../../../lib-client/objs-on-disk/file-writing-proc";
5
5
  import { LogError } from "../../../lib-client/logging/log-to-file";
6
6
  import { NewVersionUpload } from "./obj-status";
7
- import { UploadHeaderChange } from "../../../lib-client/xsp-fs/common";
8
- type UploadEvent = web3n.files.UploadEvent;
7
+ import { UploadEventSink, UploadHeaderChange } from "../../../lib-client/xsp-fs/common";
9
8
  export type FileWriteTapOperator = MonoTypeOperatorFunction<FileWrite[]>;
10
9
  export declare class UpSyncer {
11
10
  private readonly remoteStorage;
@@ -23,7 +22,7 @@ export declare class UpSyncer {
23
22
  */
24
23
  tapFileWrite(obj: SyncedObj, isNew: boolean, newVersion: number, baseVersion?: number): FileWriteTapOperator;
25
24
  removeCurrentVersionOf(obj: SyncedObj): Promise<void>;
26
- startUploadFromDisk(obj: SyncedObj, localVersion: number, uploadVersion: number, uploadHeader: UploadHeaderChange | undefined, createOnRemote: boolean, eventSink: (event: UploadEvent) => void): Promise<{
25
+ startUploadFromDisk(obj: SyncedObj, localVersion: number, uploadVersion: number, uploadHeader: UploadHeaderChange | undefined, createOnRemote: boolean, eventSink: UploadEventSink | undefined): Promise<{
27
26
  completion: Promise<void>;
28
27
  uploadTaskId: number;
29
28
  }>;
@@ -33,4 +32,3 @@ export interface UploadStatusRecorder {
33
32
  recordUploadCancellation(info: NewVersionUpload): Promise<void>;
34
33
  recordUploadInterimState(info: NewVersionUpload): Promise<void>;
35
34
  }
36
- export {};
@@ -88,7 +88,7 @@ class UpSyncer {
88
88
  if (uploadHeader) {
89
89
  await obj.saveUploadHeaderFile(uploadHeader);
90
90
  }
91
- const task = await UploadTask.for(obj, localVersion, uploadVersion, uploadHeader === null || uploadHeader === void 0 ? void 0 : uploadHeader.uploadHeader, syncedBase, createOnRemote, uploadTaskId, eventSink, this.remoteStorage, this.execPools, async () => {
91
+ const task = await UploadTask.for(obj, localVersion, uploadVersion, uploadHeader === null || uploadHeader === void 0 ? void 0 : uploadHeader.uploadHeader, syncedBase, createOnRemote, uploadTaskId, eventSink, this.remoteStorage, async () => {
92
92
  if (this.tasksByIds.delete(task.taskId)) {
93
93
  this.tasksByObjIds.delete(task.objId);
94
94
  }
@@ -113,13 +113,12 @@ exports.UpSyncer = UpSyncer;
113
113
  Object.freeze(UpSyncer.prototype);
114
114
  Object.freeze(UpSyncer);
115
115
  class UploadTask {
116
- constructor(taskId, remoteStorage, objId, objStatus, src, execPools, info, uploadHeader, doAtCompletion, eventSink) {
116
+ constructor(taskId, remoteStorage, objId, objStatus, src, info, uploadHeader, doAtCompletion, eventSink) {
117
117
  this.taskId = taskId;
118
118
  this.remoteStorage = remoteStorage;
119
119
  this.objId = objId;
120
120
  this.objStatus = objStatus;
121
121
  this.src = src;
122
- this.execPools = execPools;
123
122
  this.info = info;
124
123
  this.uploadHeader = uploadHeader;
125
124
  this.doAtCompletion = doAtCompletion;
@@ -130,7 +129,7 @@ class UploadTask {
130
129
  this.emitUploadEvent('upload-started', { totalBytesToUpload: this.totalBytesToUpload });
131
130
  Object.seal(this);
132
131
  }
133
- static async for(obj, localVersion, uploadVersion, uploadHeader, syncedBase, createObj, taskId, eventSink, remoteStorage, execPools, doAtCompletion) {
132
+ static async for(obj, localVersion, uploadVersion, uploadHeader, syncedBase, createObj, taskId, eventSink, remoteStorage, doAtCompletion) {
134
133
  const src = await obj.getObjSrcFromLocalAndSyncedBranch(localVersion);
135
134
  let needUpload;
136
135
  if (syncedBase) {
@@ -149,7 +148,7 @@ class UploadTask {
149
148
  };
150
149
  const objStatus = obj.statusObj();
151
150
  await objStatus.recordUploadStart(info);
152
- return new UploadTask(taskId, remoteStorage, obj.objId, objStatus, src, execPools, info, uploadHeader, doAtCompletion, eventSink);
151
+ return new UploadTask(taskId, remoteStorage, obj.objId, objStatus, src, info, uploadHeader, doAtCompletion, eventSink);
153
152
  }
154
153
  neededExecutor() {
155
154
  return (!this.info.needUpload ? undefined : this.execLabel);
@@ -158,7 +157,8 @@ class UploadTask {
158
157
  return this.uploadCompletion.promise;
159
158
  }
160
159
  emitUploadEvent(type, fields) {
161
- this.eventSink({
160
+ var _a;
161
+ (_a = this.eventSink) === null || _a === void 0 ? void 0 : _a.call(this, {
162
162
  type,
163
163
  localVersion: this.info.localVersion,
164
164
  uploadTaskId: this.taskId,
@@ -169,7 +169,7 @@ class UploadTask {
169
169
  }
170
170
  async process() {
171
171
  if (!this.info.needUpload) {
172
- return;
172
+ return true;
173
173
  }
174
174
  try {
175
175
  const upload = this.info.needUpload;
@@ -194,17 +194,22 @@ class UploadTask {
194
194
  }
195
195
  await this.objStatus.recordUploadInterimState(this.info);
196
196
  if (this.info.needUpload) {
197
- this.emitUploadEvent('upload-progress', {
198
- totalBytesToUpload: this.totalBytesToUpload,
199
- bytesLeftToUpload: (0, obj_status_1.countBytesIn)(this.info)
200
- });
201
- this.execPools.add(this);
197
+ if (this.eventSink) {
198
+ this.emitUploadEvent('upload-progress', {
199
+ totalBytesToUpload: this.totalBytesToUpload,
200
+ bytesLeftToUpload: (0, obj_status_1.countBytesIn)(this.info)
201
+ });
202
+ }
203
+ return false;
202
204
  }
203
205
  else {
204
206
  await this.doAtCompletion().finally(() => {
205
207
  this.uploadCompletion.resolve();
206
- this.emitUploadEvent('upload-done', {});
208
+ if (this.eventSink) {
209
+ this.emitUploadEvent('upload-done', {});
210
+ }
207
211
  });
212
+ return true;
208
213
  }
209
214
  }
210
215
  catch (exc) {
@@ -215,6 +220,7 @@ class UploadTask {
215
220
  cause: exc
216
221
  }));
217
222
  await this.objStatus.recordUploadCancellation(this.info);
223
+ return true;
218
224
  }
219
225
  }
220
226
  async startOrderedUpload(upload) {
@@ -3,6 +3,7 @@ import { ProtoType } from '../lib-client/protobuf-type';
3
3
  import { ExposedFn, EnvelopeBody, Caller, CoreSideServices } from "../ipc-via-protobuf/connector";
4
4
  type ReadonlyFile = web3n.files.ReadonlyFile;
5
5
  type ReadonlyFileVersionedAPI = web3n.files.ReadonlyFileVersionedAPI;
6
+ type ReadonlyFileSyncAPI = web3n.files.ReadonlyFileSyncAPI;
6
7
  type WritableFile = web3n.files.WritableFile;
7
8
  type WritableFileVersionedAPI = web3n.files.WritableFileVersionedAPI;
8
9
  type WritableFileSyncAPI = web3n.files.WritableFileSyncAPI;
@@ -147,6 +148,15 @@ export declare namespace vGetByteSink {
147
148
  function wrapService(fn: WritableFileVersionedAPI['getByteSink'], expServices: CoreSideServices): ExposedFn;
148
149
  function makeCaller(caller: Caller, objPath: string[]): WritableFileVersionedAPI['getByteSink'];
149
150
  }
151
+ export declare namespace vsStartDownload {
152
+ const replyType: ProtoType<{
153
+ startedDownload?: {
154
+ downloadTaskId: number;
155
+ };
156
+ }>;
157
+ function wrapService(fn: ReadonlyFileSyncAPI['startDownload']): ExposedFn;
158
+ function makeCaller(caller: Caller, objPath: string[]): ReadonlyFileSyncAPI['startDownload'];
159
+ }
150
160
  export interface OptionsToUploadLocalMsg {
151
161
  localVersion?: Value<number>;
152
162
  uploadVersion?: Value<number>;