core-3nweb-client-lib 0.27.0 → 0.27.4

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 (81) hide show
  1. package/build/api-defs/files.d.ts +56 -26
  2. package/build/core/asmail/config/index.d.ts +2 -2
  3. package/build/core/asmail/config/index.js +2 -2
  4. package/build/core/asmail/config/invitations-anon.d.ts +10 -24
  5. package/build/core/asmail/config/invitations-anon.js +43 -31
  6. package/build/core/asmail/config/published-intro-key.d.ts +11 -22
  7. package/build/core/asmail/config/published-intro-key.js +47 -38
  8. package/build/core/asmail/inbox/attachments/fs.d.ts +2 -1
  9. package/build/core/asmail/inbox/attachments/fs.js +4 -3
  10. package/build/core/asmail/inbox/index.js +2 -2
  11. package/build/core/asmail/index.d.ts +1 -1
  12. package/build/core/asmail/index.js +2 -2
  13. package/build/core/asmail/keyring/correspondent-keys.d.ts +2 -2
  14. package/build/core/asmail/keyring/correspondent-keys.js +1 -1
  15. package/build/core/asmail/keyring/index.d.ts +9 -29
  16. package/build/core/asmail/keyring/index.js +82 -69
  17. package/build/core/id-manager/index.d.ts +43 -0
  18. package/build/core/{id-manager.js → id-manager/index.js} +33 -114
  19. package/build/core/id-manager/key-storage.d.ts +21 -0
  20. package/build/core/id-manager/key-storage.js +96 -0
  21. package/build/core/index.js +22 -25
  22. package/build/core/sign-in.d.ts +1 -2
  23. package/build/core/sign-in.js +5 -14
  24. package/build/core/sign-up.d.ts +2 -0
  25. package/build/core/sign-up.js +2 -1
  26. package/build/core/storage/index.d.ts +4 -2
  27. package/build/core/storage/index.js +36 -57
  28. package/build/core/storage/local/storage.d.ts +1 -1
  29. package/build/core/storage/synced/obj-files-gc.d.ts +1 -4
  30. package/build/core/storage/synced/obj-files-gc.js +1 -18
  31. package/build/core/storage/synced/obj-files.d.ts +11 -1
  32. package/build/core/storage/synced/obj-files.js +59 -34
  33. package/build/core/storage/synced/obj-status.d.ts +19 -7
  34. package/build/core/storage/synced/obj-status.js +158 -83
  35. package/build/core/storage/synced/storage.d.ts +7 -2
  36. package/build/core/storage/synced/storage.js +38 -15
  37. package/build/core/storage/synced/upsyncer.d.ts +4 -4
  38. package/build/core/storage/synced/upsyncer.js +14 -9
  39. package/build/ipc-via-protobuf/file.d.ts +7 -0
  40. package/build/ipc-via-protobuf/file.js +60 -27
  41. package/build/ipc-via-protobuf/fs.js +55 -38
  42. package/build/lib-client/3nstorage/exceptions.d.ts +13 -1
  43. package/build/lib-client/3nstorage/exceptions.js +9 -3
  44. package/build/lib-client/3nstorage/service.d.ts +6 -2
  45. package/build/lib-client/3nstorage/service.js +33 -17
  46. package/build/lib-client/3nstorage/util/file-based-json.js +2 -1
  47. package/build/lib-client/3nstorage/util/for-arrays.d.ts +1 -0
  48. package/build/lib-client/3nstorage/util/for-arrays.js +32 -0
  49. package/build/lib-client/3nstorage/xsp-fs/common.d.ts +5 -4
  50. package/build/lib-client/3nstorage/xsp-fs/common.js +1 -0
  51. package/build/lib-client/3nstorage/xsp-fs/file-node.d.ts +5 -10
  52. package/build/lib-client/3nstorage/xsp-fs/file-node.js +43 -45
  53. package/build/lib-client/3nstorage/xsp-fs/file.d.ts +7 -6
  54. package/build/lib-client/3nstorage/xsp-fs/file.js +14 -20
  55. package/build/lib-client/3nstorage/xsp-fs/folder-node.d.ts +16 -5
  56. package/build/lib-client/3nstorage/xsp-fs/folder-node.js +238 -68
  57. package/build/lib-client/3nstorage/xsp-fs/fs.d.ts +18 -17
  58. package/build/lib-client/3nstorage/xsp-fs/fs.js +32 -37
  59. package/build/lib-client/3nstorage/xsp-fs/node-in-fs.d.ts +15 -11
  60. package/build/lib-client/3nstorage/xsp-fs/node-in-fs.js +72 -22
  61. package/build/lib-client/3nstorage/xsp-fs/xsp-payload-v1.js +1 -1
  62. package/build/lib-client/local-files/device-fs.js +11 -11
  63. package/build/lib-client/objs-on-disk/obj-on-disk.d.ts +5 -2
  64. package/build/lib-client/objs-on-disk/obj-on-disk.js +16 -1
  65. package/build/lib-client/user-with-mid-session.d.ts +2 -1
  66. package/build/lib-client/user-with-mid-session.js +7 -1
  67. package/build/lib-common/async-fs-node.js +8 -8
  68. package/build/lib-common/exceptions/file.d.ts +4 -2
  69. package/build/lib-common/exceptions/file.js +24 -58
  70. package/build/lib-common/ipc/generic-ipc.js +5 -4
  71. package/build/lib-common/objs-on-disk/file-layout.js +1 -1
  72. package/build/lib-common/objs-on-disk/utils.js +1 -1
  73. package/build/lib-common/service-api/3nstorage/owner.d.ts +8 -9
  74. package/build/lib-common/service-api/3nstorage/owner.js +2 -1
  75. package/build/protos/asmail.proto.js +5943 -4348
  76. package/build/protos/file.proto.js +874 -0
  77. package/build/protos/fs.proto.js +7014 -5419
  78. package/package.json +3 -2
  79. package/protos/file.proto +23 -7
  80. package/protos/fs.proto +27 -13
  81. package/build/core/id-manager.d.ts +0 -46
@@ -32,6 +32,7 @@ const pipe_1 = require("../../../lib-common/byte-streaming/pipe");
32
32
  const buffer_utils_1 = require("../../../lib-common/buffer-utils");
33
33
  const rxjs_1 = require("rxjs");
34
34
  const operators_1 = require("rxjs/operators");
35
+ const node_in_fs_1 = require("./node-in-fs");
35
36
  const utils_for_observables_1 = require("../../../lib-common/utils-for-observables");
36
37
  function splitPathIntoParts(path) {
37
38
  return path_1.posix.resolve('/', path).split('/').filter(part => !!part);
@@ -68,7 +69,7 @@ class XspFS {
68
69
  }
69
70
  storage() {
70
71
  if (!this.store) {
71
- throw (0, file_1.makeFileException)(file_1.Code.storageClosed, this.name);
72
+ throw (0, file_1.makeFileException)('storageClosed', this.name);
72
73
  }
73
74
  return this.store;
74
75
  }
@@ -146,8 +147,10 @@ class XspFS {
146
147
  const folder = (await parentFolder.getFolder(folderName)
147
148
  .catch(setExcPath(path)));
148
149
  if (!removeContent && !folder.isEmpty()) {
149
- throw (0, file_1.makeFileException)(file_1.Code.notEmpty, path);
150
+ throw (0, file_1.makeFileException)('notEmpty', path);
150
151
  }
152
+ // note that internal folder.delete() removes all children as a matter
153
+ // of not leaving inaccessible nodes, i.e. content is removed implicitly
151
154
  await parentFolder.removeChild(folder);
152
155
  }
153
156
  async deleteFile(path) {
@@ -252,17 +255,11 @@ class XspFS {
252
255
  return true;
253
256
  }
254
257
  else if (throwIfMissing) {
255
- let code = '';
256
- if (type === 'file') {
257
- code = file_1.Code.notFile;
258
+ switch (type) {
259
+ case 'file': throw (0, file_1.makeFileException)('notFile', path);
260
+ case 'folder': throw (0, file_1.makeFileException)('notDirectory', path);
261
+ case 'link': throw (0, file_1.makeFileException)('notLink', path);
258
262
  }
259
- else if (type === 'folder') {
260
- code = file_1.Code.notDirectory;
261
- }
262
- else if (type === 'link') {
263
- code = file_1.Code.notLink;
264
- }
265
- throw (0, file_1.makeFileException)(code, path);
266
263
  }
267
264
  else {
268
265
  return false;
@@ -415,14 +412,14 @@ class XspFS {
415
412
  const exists = await this.checkFilePresence(path);
416
413
  if (exists) {
417
414
  if (flags.create && flags.exclusive) {
418
- throw (0, file_1.makeFileException)(file_1.Code.alreadyExists, path);
415
+ throw (0, file_1.makeFileException)('alreadyExists', path);
419
416
  }
420
417
  const fNode = await this.v.getOrCreateFile(path, flags);
421
418
  return (0, files_1.wrapWritableFile)(file_2.FileObject.makeExisting(fNode, true));
422
419
  }
423
420
  else {
424
421
  if (!flags.create) {
425
- throw (0, file_1.makeFileException)(file_1.Code.notFound, path);
422
+ throw (0, file_1.makeFileException)('notFound', path);
426
423
  }
427
424
  return (0, files_1.wrapWritableFile)(file_2.FileObject.makeForNotExisiting(path_1.posix.basename(path), () => this.v.getOrCreateFile(path, flags), !!this.v.sync));
428
425
  }
@@ -512,7 +509,7 @@ class V {
512
509
  }
513
510
  getRootIfNotClosed(excPath) {
514
511
  if (!this.rootNode) {
515
- throw (0, file_1.makeFileException)(file_1.Code.storageClosed, excPath);
512
+ throw (0, file_1.makeFileException)('storageClosed', excPath);
516
513
  }
517
514
  return this.rootNode;
518
515
  }
@@ -525,7 +522,7 @@ class V {
525
522
  .catch(setExcPath(path));
526
523
  if (file) {
527
524
  if (exclusive) {
528
- throw (0, file_1.makeFileException)(file_1.Code.alreadyExists, path);
525
+ throw (0, file_1.makeFileException)('alreadyExists', path);
529
526
  }
530
527
  }
531
528
  else {
@@ -554,58 +551,56 @@ class V {
554
551
  const node = await this.get(path);
555
552
  return node.updateXAttrs(changes);
556
553
  }
557
- async getXAttr(path, xaName) {
554
+ async getXAttr(path, xaName, flags) {
558
555
  const node = await this.get(path);
559
- const attr = node.getXAttr(xaName);
560
- return { attr, version: node.version };
556
+ return await node.getXAttr(xaName, flags);
561
557
  }
562
- async listXAttrs(path) {
558
+ async listXAttrs(path, flags) {
563
559
  const node = await this.get(path);
564
- return {
565
- lst: node.listXAttrs(),
566
- version: node.version
567
- };
560
+ return node.listXAttrs(flags);
568
561
  }
569
- async listFolder(path) {
562
+ async listFolder(path, flags) {
570
563
  const root = this.getRootIfNotClosed(path);
571
564
  const folder = await root.getFolderInThisSubTree(splitPathIntoParts(path), false).catch(setExcPath(path));
572
- return folder.list();
565
+ return ((0, node_in_fs_1.shouldReadCurrentVersion)(flags) ?
566
+ folder.list() :
567
+ folder.listNonCurrent(flags));
573
568
  }
574
569
  async writeBytes(path, bytes, flags = WRITE_NONEXCL_FLAGS) {
575
570
  this.ensureIsWritable();
576
571
  const f = await this.getOrCreateFile(path, flags);
577
572
  return f.save(bytes);
578
573
  }
579
- async readBytes(path, start, end) {
574
+ async readBytes(path, start, end, flags) {
580
575
  const file = await this.getOrCreateFile(path, {});
581
- return await file.readBytes(start, end);
576
+ return await file.readBytes(start, end, flags);
582
577
  }
583
578
  writeTxtFile(path, txt, flags = WRITE_NONEXCL_FLAGS) {
584
579
  const bytes = buffer_utils_1.utf8.pack(txt);
585
580
  return this.writeBytes(path, bytes, flags);
586
581
  }
587
- async readTxtFile(path) {
588
- const { bytes, version } = await this.readBytes(path);
582
+ async readTxtFile(path, flags) {
583
+ const { bytes, version } = await this.readBytes(path, undefined, undefined, flags);
589
584
  try {
590
585
  const txt = (bytes ? buffer_utils_1.utf8.open(bytes) : '');
591
586
  return { txt, version };
592
587
  }
593
588
  catch (err) {
594
- throw (0, file_1.makeFileException)(file_1.Code.parsingError, path, err);
589
+ throw (0, file_1.makeFileException)('parsingError', path, err);
595
590
  }
596
591
  }
597
592
  writeJSONFile(path, json, flags = WRITE_NONEXCL_FLAGS) {
598
593
  const txt = JSON.stringify(json);
599
594
  return this.writeTxtFile(path, txt, flags);
600
595
  }
601
- async readJSONFile(path) {
602
- const { txt, version } = await this.readTxtFile(path);
596
+ async readJSONFile(path, flags) {
597
+ const { txt, version } = await this.readTxtFile(path, flags);
603
598
  try {
604
599
  const json = JSON.parse(txt);
605
600
  return { json, version };
606
601
  }
607
602
  catch (err) {
608
- throw (0, file_1.makeFileException)(file_1.Code.parsingError, path, err);
603
+ throw (0, file_1.makeFileException)('parsingError', path, err);
609
604
  }
610
605
  }
611
606
  async getByteSink(path, flags = WRITE_NONEXCL_FLAGS) {
@@ -613,9 +608,9 @@ class V {
613
608
  const f = await this.getOrCreateFile(path, flags);
614
609
  return f.writeSink(flags.truncate, flags.currentVersion);
615
610
  }
616
- async getByteSource(path) {
611
+ async getByteSource(path, flags) {
617
612
  const f = await this.getOrCreateFile(path, {});
618
- return f.readSrc();
613
+ return f.readSrc(flags);
619
614
  }
620
615
  }
621
616
  Object.freeze(V.prototype);
@@ -780,7 +775,7 @@ class S {
780
775
  async getFolderNode(path) {
781
776
  const node = await this.n.get(path);
782
777
  if (node.type !== 'folder') {
783
- throw (0, file_1.makeFileException)(file_1.Code.notDirectory, path);
778
+ throw (0, file_1.makeFileException)('notDirectory', path);
784
779
  }
785
780
  return node;
786
781
  }
@@ -1,4 +1,4 @@
1
- import { FSChangeSrc, Node, NodeType, Storage, SyncedStorage } from './common';
1
+ import { FSChangeSrc, Node, NodeType, Storage, SyncedStorage, UploadHeaderChange } from './common';
2
2
  import { Observable } from 'rxjs';
3
3
  import { CommonAttrs, XAttrs } from './attrs';
4
4
  import { NodePersistance } from './node-persistence';
@@ -9,6 +9,7 @@ declare type XAttrsChanges = web3n.files.XAttrsChanges;
9
9
  declare type SyncStatus = web3n.files.SyncStatus;
10
10
  declare type OptionsToAdopteRemote = web3n.files.OptionsToAdopteRemote;
11
11
  declare type OptionsToUploadLocal = web3n.files.OptionsToUploadLocal;
12
+ declare type VersionedReadFlags = web3n.files.VersionedReadFlags;
12
13
  export declare abstract class NodeInFS<P extends NodePersistance> implements Node {
13
14
  protected readonly storage: Storage;
14
15
  readonly type: NodeType;
@@ -24,6 +25,7 @@ export declare abstract class NodeInFS<P extends NodePersistance> implements Nod
24
25
  protected setCurrentVersion(newVersion: number): void;
25
26
  readonly isInSyncedStorage: boolean;
26
27
  protected constructor(storage: Storage, type: NodeType, name: string, objId: string, currentVersion: number, parentId: string | undefined);
28
+ protected getObjSrcOfVersion(flags: VersionedReadFlags | undefined): Promise<ObjSource>;
27
29
  private updatedXAttrs;
28
30
  protected setUpdatedParams(version: number, attrs: CommonAttrs | undefined, xattrs: XAttrs | undefined): void;
29
31
  protected getParamsForUpdate(changes: XAttrsChanges | undefined): {
@@ -32,21 +34,22 @@ export declare abstract class NodeInFS<P extends NodePersistance> implements Nod
32
34
  xattrs?: XAttrs;
33
35
  };
34
36
  updateXAttrs(changes: XAttrsChanges): Promise<number>;
35
- getXAttr(xaName: string): any;
36
- listXAttrs(): string[];
37
+ getXAttr(xaName: string, flags: VersionedReadFlags | undefined): Promise<{
38
+ attr: any;
39
+ version: number;
40
+ }>;
41
+ listXAttrs(flags: VersionedReadFlags | undefined): Promise<{
42
+ lst: string[];
43
+ version: number;
44
+ }>;
37
45
  getAttrs(): CommonAttrs;
38
46
  listVersions(): Promise<{
39
47
  current?: number;
40
48
  archived?: number[];
41
49
  }>;
42
50
  archiveCurrent(version?: number): Promise<number>;
43
- removeObj(src?: FSChangeSrc): Promise<void>;
44
- /**
45
- * This non-synchronized method deletes object from storage, and detaches
46
- * this node from storage. Make sure to call it inside access synchronization
47
- * construct.
48
- */
49
- protected delete(src: FSChangeSrc): Promise<void>;
51
+ removeNonFolderObj(src: FSChangeSrc): Promise<void>;
52
+ protected removeThisNodeAsLeaf(src: FSChangeSrc): Promise<void>;
50
53
  /**
51
54
  * This method runs node changing function in an exclusive manner.
52
55
  * Returned promise resolves to whatever change function returns.
@@ -80,6 +83,7 @@ export declare abstract class NodeInFS<P extends NodePersistance> implements Nod
80
83
  createOnRemote: boolean;
81
84
  } | undefined>;
82
85
  upload(opts: OptionsToUploadLocal | undefined): Promise<void>;
83
- private uploadHeaderChange;
86
+ protected uploadHeaderChange(localVersion: number, uploadVersion: number): Promise<UploadHeaderChange | undefined>;
84
87
  }
88
+ export declare function shouldReadCurrentVersion(flags: VersionedReadFlags | undefined): boolean;
85
89
  export {};
@@ -16,7 +16,7 @@
16
16
  this program. If not, see <http://www.gnu.org/licenses/>.
17
17
  */
18
18
  Object.defineProperty(exports, "__esModule", { value: true });
19
- exports.NodeInFS = void 0;
19
+ exports.shouldReadCurrentVersion = exports.NodeInFS = void 0;
20
20
  /**
21
21
  * Everything in this module is assumed to be inside of a file system
22
22
  * reliance set.
@@ -29,6 +29,7 @@ const exceptions_1 = require("../exceptions");
29
29
  const rxjs_1 = require("rxjs");
30
30
  const operators_1 = require("rxjs/operators");
31
31
  const attrs_1 = require("./attrs");
32
+ const assert_1 = require("../../../lib-common/assert");
32
33
  class NodeInFS {
33
34
  constructor(storage, type, name, objId, currentVersion, parentId) {
34
35
  this.storage = storage;
@@ -57,6 +58,19 @@ class NodeInFS {
57
58
  }
58
59
  this.currentVersion = newVersion;
59
60
  }
61
+ getObjSrcOfVersion(flags) {
62
+ if (flags) {
63
+ const { remoteVersion, archivedVersion } = flags;
64
+ if (remoteVersion) {
65
+ const store = this.syncedStorage();
66
+ return store.getObjSrcOfRemoteVersion(this.objId, remoteVersion);
67
+ }
68
+ else if (archivedVersion) {
69
+ return this.storage.getObjSrc(this.objId, archivedVersion, true);
70
+ }
71
+ }
72
+ return this.storage.getObjSrc(this.objId);
73
+ }
60
74
  updatedXAttrs(changes) {
61
75
  return (this.xattrs ?
62
76
  (changes ? this.xattrs.makeUpdated(changes) : this.xattrs) :
@@ -89,11 +103,39 @@ class NodeInFS {
89
103
  return this.version;
90
104
  });
91
105
  }
92
- getXAttr(xaName) {
93
- return (this.xattrs ? this.xattrs.get(xaName) : undefined);
106
+ async getXAttr(xaName, flags) {
107
+ if (shouldReadCurrentVersion(flags)) {
108
+ return {
109
+ attr: (this.xattrs ? this.xattrs.get(xaName) : undefined),
110
+ version: this.version
111
+ };
112
+ }
113
+ else {
114
+ const src = await this.getObjSrcOfVersion(flags);
115
+ const payload = await this.crypto.readonlyPayload(src);
116
+ const xattrs = await payload.getXAttrs();
117
+ return {
118
+ attr: xattrs.get(xaName),
119
+ version: src.version
120
+ };
121
+ }
94
122
  }
95
- listXAttrs() {
96
- return (this.xattrs ? this.xattrs.list() : []);
123
+ async listXAttrs(flags) {
124
+ if (shouldReadCurrentVersion(flags)) {
125
+ return {
126
+ lst: (this.xattrs ? this.xattrs.list() : []),
127
+ version: this.version
128
+ };
129
+ }
130
+ else {
131
+ const src = await this.getObjSrcOfVersion(flags);
132
+ const payload = await this.crypto.readonlyPayload(src);
133
+ const xattrs = await payload.getXAttrs();
134
+ return {
135
+ lst: xattrs.list(),
136
+ version: src.version
137
+ };
138
+ }
97
139
  }
98
140
  getAttrs() {
99
141
  return this.attrs;
@@ -124,7 +166,7 @@ class NodeInFS {
124
166
  else {
125
167
  if (version) {
126
168
  if (this.currentVersion !== version) {
127
- throw (0, file_1.makeFileException)(file_1.Code.versionMismatch, this.name);
169
+ throw (0, file_1.makeFileException)('versionMismatch', this.name);
128
170
  }
129
171
  }
130
172
  else {
@@ -135,15 +177,11 @@ class NodeInFS {
135
177
  return version;
136
178
  }
137
179
  }
138
- removeObj(src = 'local') {
139
- return this.doChange(true, () => this.delete(src));
180
+ removeNonFolderObj(src) {
181
+ (0, assert_1.assert)(this.type !== 'folder');
182
+ return this.doChange(true, () => this.removeThisNodeAsLeaf(src));
140
183
  }
141
- /**
142
- * This non-synchronized method deletes object from storage, and detaches
143
- * this node from storage. Make sure to call it inside access synchronization
144
- * construct.
145
- */
146
- async delete(src) {
184
+ async removeThisNodeAsLeaf(src) {
147
185
  await this.storage.removeObj(this.objId);
148
186
  this.storage.nodes.delete(this);
149
187
  this.currentVersion = -1;
@@ -171,11 +209,11 @@ class NodeInFS {
171
209
  this.writeProc = new synced_1.SingleProc();
172
210
  }
173
211
  if (!awaitPrevChange && this.writeProc.isProcessing()) {
174
- throw (0, file_1.makeFileException)(file_1.Code.concurrentUpdate, this.name + ` type ${this.type}`);
212
+ throw (0, file_1.makeFileException)('concurrentUpdate', this.name + ` type ${this.type}`);
175
213
  }
176
214
  const res = await this.writeProc.startOrChain(async () => {
177
215
  if (this.currentVersion < 0) {
178
- throw (0, file_1.makeFileException)(file_1.Code.notFound, this.name, `Object is marked removed`);
216
+ throw (0, file_1.makeFileException)('notFound', this.name, `Object is marked removed`);
179
217
  }
180
218
  try {
181
219
  const res = await change();
@@ -187,17 +225,17 @@ class NodeInFS {
187
225
  }
188
226
  if (exc.type === 'storage') {
189
227
  if (exc.concurrentTransaction) {
190
- throw (0, file_1.makeFileException)(file_1.Code.concurrentUpdate, this.name, exc);
228
+ throw (0, file_1.makeFileException)('concurrentUpdate', this.name, exc);
191
229
  }
192
230
  else if (exc.objNotFound) {
193
- throw (0, file_1.makeFileException)(file_1.Code.notFound, this.name, exc);
231
+ throw (0, file_1.makeFileException)('notFound', this.name, exc);
194
232
  }
195
233
  }
196
234
  else if ((exc.type === 'file')
197
235
  || (exc.type === 'fs-sync')) {
198
236
  throw exc;
199
237
  }
200
- throw (0, file_1.makeFileException)(file_1.Code.ioError, this.name, exc);
238
+ throw (0, file_1.makeFileException)('ioError', this.name, exc);
201
239
  }
202
240
  });
203
241
  return res;
@@ -258,7 +296,7 @@ class NodeInFS {
258
296
  async updateStatusInfo() {
259
297
  const storage = this.syncedStorage();
260
298
  const status = await storage.updateStatusInfo(this.objId);
261
- return await this.syncStatus();
299
+ return status;
262
300
  }
263
301
  isSyncedVersionOnDisk(version) {
264
302
  const storage = this.syncedStorage();
@@ -350,8 +388,7 @@ class NodeInFS {
350
388
  return;
351
389
  }
352
390
  const { localVersion, createOnRemote, uploadVersion } = toUpload;
353
- const uploadHeader = ((localVersion === uploadVersion) ? undefined :
354
- await this.uploadHeaderChange(localVersion, uploadVersion));
391
+ const uploadHeader = await this.uploadHeaderChange(localVersion, uploadVersion);
355
392
  const storage = this.syncedStorage();
356
393
  await storage.upload(this.objId, localVersion, uploadVersion, uploadHeader, createOnRemote);
357
394
  await this.doChange(true, async () => {
@@ -366,6 +403,9 @@ class NodeInFS {
366
403
  }
367
404
  }
368
405
  async uploadHeaderChange(localVersion, uploadVersion) {
406
+ if (localVersion === uploadVersion) {
407
+ return;
408
+ }
369
409
  const currentSrc = await this.storage.getObjSrc(this.objId, localVersion);
370
410
  const localHeader = await currentSrc.readHeader();
371
411
  const uploadHeader = await this.crypto.reencryptHeader(localHeader, uploadVersion);
@@ -389,4 +429,14 @@ function copyWithPathIfRemoteEvent(e, path) {
389
429
  return e;
390
430
  }
391
431
  }
432
+ function shouldReadCurrentVersion(flags) {
433
+ if (flags) {
434
+ const { archivedVersion, remoteVersion } = flags;
435
+ if (archivedVersion || remoteVersion) {
436
+ return false;
437
+ }
438
+ }
439
+ return true;
440
+ }
441
+ exports.shouldReadCurrentVersion = shouldReadCurrentVersion;
392
442
  Object.freeze(exports);
@@ -82,6 +82,6 @@ class ReadonlyPayloadV1 {
82
82
  Object.freeze(ReadonlyPayloadV1.prototype);
83
83
  Object.freeze(ReadonlyPayloadV1);
84
84
  function makeEndlessException() {
85
- return (0, file_1.makeFileException)(file_1.Code.isEndless, '');
85
+ return (0, file_1.makeFileException)('isEndless', '');
86
86
  }
87
87
  Object.freeze(exports);
@@ -62,10 +62,10 @@ async function makeFolder(root, path, exclusive = false) {
62
62
  continue;
63
63
  }
64
64
  if (!stats.isDirectory()) {
65
- throw (0, file_1.makeFileException)(file_1.Code.notDirectory, path.slice(0, i + 1).join('/'));
65
+ throw (0, file_1.makeFileException)('notDirectory', path.slice(0, i + 1).join('/'));
66
66
  }
67
67
  else if ((i === lastIndex) && exclusive) {
68
- throw (0, file_1.makeFileException)(file_1.Code.alreadyExists, path.join('/'));
68
+ throw (0, file_1.makeFileException)('alreadyExists', path.join('/'));
69
69
  }
70
70
  }
71
71
  }
@@ -227,10 +227,10 @@ class DeviceFS {
227
227
  await fs.lstat(root)
228
228
  .then(stat => {
229
229
  if (create && exclusive) {
230
- throw (0, file_1.makeFileException)(file_1.Code.alreadyExists, root);
230
+ throw (0, file_1.makeFileException)('alreadyExists', root);
231
231
  }
232
232
  if (!stat.isDirectory()) {
233
- throw (0, file_1.makeFileException)(file_1.Code.notDirectory, root);
233
+ throw (0, file_1.makeFileException)('notDirectory', root);
234
234
  }
235
235
  }, async (e) => {
236
236
  if (!e.notFound || !create) {
@@ -455,7 +455,7 @@ class DeviceFS {
455
455
  return txt;
456
456
  }
457
457
  catch (err) {
458
- throw (0, file_1.makeFileException)(file_1.Code.parsingError, path, err);
458
+ throw (0, file_1.makeFileException)('parsingError', path, err);
459
459
  }
460
460
  }
461
461
  writeJSONFile(path, json, flags = WRITE_NONEXCL_FLAGS) {
@@ -469,7 +469,7 @@ class DeviceFS {
469
469
  return json;
470
470
  }
471
471
  catch (err) {
472
- throw (0, file_1.makeFileException)(file_1.Code.parsingError, path, err);
472
+ throw (0, file_1.makeFileException)('parsingError', path, err);
473
473
  }
474
474
  }
475
475
  async deleteFile(path) {
@@ -557,7 +557,7 @@ class DeviceFS {
557
557
  const dstPath = this.root + '/' + dst.join('/');
558
558
  await fs.lstat(dstPath)
559
559
  .then(() => {
560
- throw (0, file_1.makeFileException)(file_1.Code.alreadyExists, newPath);
560
+ throw (0, file_1.makeFileException)('alreadyExists', newPath);
561
561
  }, (exc) => {
562
562
  if (!exc.notFound) {
563
563
  throw exc;
@@ -692,10 +692,10 @@ class DeviceFS {
692
692
  async writableFile(path, flags = WRITE_NONEXCL_FLAGS) {
693
693
  const exists = await this.checkFilePresence(path);
694
694
  if (exists && flags.create && flags.exclusive) {
695
- throw (0, file_1.makeFileException)(file_1.Code.alreadyExists, path);
695
+ throw (0, file_1.makeFileException)('alreadyExists', path);
696
696
  }
697
697
  if (!exists && !flags.create) {
698
- throw (0, file_1.makeFileException)(file_1.Code.notFound, path);
698
+ throw (0, file_1.makeFileException)('notFound', path);
699
699
  }
700
700
  return (0, files_1.wrapWritableFile)(new FileObject(this, path, exists, true));
701
701
  }
@@ -765,7 +765,7 @@ class DeviceFS {
765
765
  }
766
766
  try {
767
767
  if (observer.error) {
768
- observer.error((0, file_1.makeFileException)(sig, path, { code, sig }));
768
+ observer.error((0, file_1.makeFileExceptionFromCode)(sig, path, { code, sig }));
769
769
  }
770
770
  else if (observer.complete) {
771
771
  observer.complete();
@@ -876,7 +876,7 @@ async function checkFolderPresence(path) {
876
876
  throw (0, file_1.maskPathInExc)(0, e);
877
877
  });
878
878
  if (!stat.isDirectory()) {
879
- throw (0, file_1.makeFileException)(file_1.Code.notDirectory, path);
879
+ throw (0, file_1.makeFileException)('notDirectory', path);
880
880
  }
881
881
  }
882
882
  class FileObject {
@@ -38,10 +38,13 @@ export declare class ObjOnDisk {
38
38
  diff: DiffInfo;
39
39
  newSegsPackOrder: FiniteChunk[];
40
40
  };
41
+ private segsThatNeedDownload;
42
+ doesFileNeedDownload(): boolean;
43
+ downloadMissingSections(): Promise<void>;
41
44
  }
42
45
  export interface ObjDownloader {
43
- getLayoutWithHeaderAndFirstSegs(objId: ObjId, version: number): Promise<InitDownloadParts>;
44
- getSegs(objId: ObjId, version: number, start: number, end: number): Promise<Uint8Array>;
46
+ getLayoutWithHeaderAndFirstSegs: (objId: ObjId, version: number) => Promise<InitDownloadParts>;
47
+ getSegs: (objId: ObjId, version: number, start: number, end: number) => Promise<Uint8Array>;
45
48
  }
46
49
  export interface InitDownloadParts {
47
50
  layout: Layout;
@@ -192,6 +192,20 @@ class ObjOnDisk {
192
192
  diffFromBase() {
193
193
  return this.objFile.diffFromBase();
194
194
  }
195
+ segsThatNeedDownload() {
196
+ const totalLen = this.objFile.getTotalSegsLen();
197
+ const allSegs = this.objFile.segsLocations(0, totalLen);
198
+ return allSegs.filter(({ type }) => (type === 'new'));
199
+ }
200
+ doesFileNeedDownload() {
201
+ return (this.segsThatNeedDownload().length === 0);
202
+ }
203
+ async downloadMissingSections() {
204
+ const needDownload = this.segsThatNeedDownload();
205
+ for (const chunk of needDownload) {
206
+ await this.downloadAndSaveSegsChunk(chunk);
207
+ }
208
+ }
195
209
  }
196
210
  exports.ObjOnDisk = ObjOnDisk;
197
211
  Object.freeze(ObjOnDisk.prototype);
@@ -223,7 +237,8 @@ class ByteSourceFromObjOnDisk {
223
237
  async getSize() {
224
238
  const size = this.totalSegsLen();
225
239
  return ((typeof size === 'number') ?
226
- { size, isEndless: false } : { size: 0, isEndless: true });
240
+ { size, isEndless: false } :
241
+ { size: 0, isEndless: true });
227
242
  }
228
243
  async seek(offset) {
229
244
  (0, assert_1.assert)(Number.isInteger(offset) && (offset >= 0), 'Illegal offset is given to seek: ' + offset);
@@ -8,7 +8,7 @@ import * as WebSocket from 'ws';
8
8
  export declare type IGetMailerIdSigner = () => Promise<mid.MailerIdSigner>;
9
9
  export declare abstract class ServiceUser {
10
10
  readonly userId: string;
11
- private readonly getSigner;
11
+ private getSigner;
12
12
  private getInitServiceURI;
13
13
  protected readonly net: NetClient;
14
14
  private uri;
@@ -28,6 +28,7 @@ export declare abstract class ServiceUser {
28
28
  }, getSigner: IGetMailerIdSigner | undefined, getInitServiceURI: () => Promise<string>, net: NetClient);
29
29
  private get isUriSet();
30
30
  private throwOnBadServiceURI;
31
+ protected setGetterOfSigner(getSigner: IGetMailerIdSigner): void;
31
32
  /**
32
33
  * This initializes service uri, if it hasn't been set, yet.
33
34
  * Else, this function does nothing.
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /*
3
- Copyright (C) 2015, 2017, 2020 3NSoft Inc.
3
+ Copyright (C) 2015, 2017, 2020, 2022 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
@@ -72,6 +72,12 @@ class ServiceUser {
72
72
  throw new Error(`Service uri is not a string: ${this.serviceURI}`);
73
73
  }
74
74
  }
75
+ setGetterOfSigner(getSigner) {
76
+ if (this.getSigner) {
77
+ throw new Error(`getSigner is already set`);
78
+ }
79
+ this.getSigner = getSigner;
80
+ }
75
81
  /**
76
82
  * This initializes service uri, if it hasn't been set, yet.
77
83
  * Else, this function does nothing.