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.
- package/build/api-defs/files.d.ts +56 -26
- package/build/core/asmail/config/index.d.ts +2 -2
- package/build/core/asmail/config/index.js +2 -2
- package/build/core/asmail/config/invitations-anon.d.ts +10 -24
- package/build/core/asmail/config/invitations-anon.js +43 -31
- package/build/core/asmail/config/published-intro-key.d.ts +11 -22
- package/build/core/asmail/config/published-intro-key.js +47 -38
- package/build/core/asmail/inbox/attachments/fs.d.ts +2 -1
- package/build/core/asmail/inbox/attachments/fs.js +4 -3
- package/build/core/asmail/inbox/index.js +2 -2
- package/build/core/asmail/index.d.ts +1 -1
- package/build/core/asmail/index.js +2 -2
- package/build/core/asmail/keyring/correspondent-keys.d.ts +2 -2
- package/build/core/asmail/keyring/correspondent-keys.js +1 -1
- package/build/core/asmail/keyring/index.d.ts +9 -29
- package/build/core/asmail/keyring/index.js +82 -69
- package/build/core/id-manager/index.d.ts +43 -0
- package/build/core/{id-manager.js → id-manager/index.js} +33 -114
- package/build/core/id-manager/key-storage.d.ts +21 -0
- package/build/core/id-manager/key-storage.js +96 -0
- package/build/core/index.js +22 -25
- package/build/core/sign-in.d.ts +1 -2
- package/build/core/sign-in.js +5 -14
- package/build/core/sign-up.d.ts +2 -0
- package/build/core/sign-up.js +2 -1
- package/build/core/storage/index.d.ts +4 -2
- package/build/core/storage/index.js +36 -57
- package/build/core/storage/local/storage.d.ts +1 -1
- package/build/core/storage/synced/obj-files-gc.d.ts +1 -4
- package/build/core/storage/synced/obj-files-gc.js +1 -18
- package/build/core/storage/synced/obj-files.d.ts +11 -1
- package/build/core/storage/synced/obj-files.js +59 -34
- package/build/core/storage/synced/obj-status.d.ts +19 -7
- package/build/core/storage/synced/obj-status.js +158 -83
- package/build/core/storage/synced/storage.d.ts +7 -2
- package/build/core/storage/synced/storage.js +38 -15
- package/build/core/storage/synced/upsyncer.d.ts +4 -4
- package/build/core/storage/synced/upsyncer.js +14 -9
- package/build/ipc-via-protobuf/file.d.ts +7 -0
- package/build/ipc-via-protobuf/file.js +60 -27
- package/build/ipc-via-protobuf/fs.js +55 -38
- package/build/lib-client/3nstorage/exceptions.d.ts +13 -1
- package/build/lib-client/3nstorage/exceptions.js +9 -3
- package/build/lib-client/3nstorage/service.d.ts +6 -2
- package/build/lib-client/3nstorage/service.js +33 -17
- package/build/lib-client/3nstorage/util/file-based-json.js +2 -1
- package/build/lib-client/3nstorage/util/for-arrays.d.ts +1 -0
- package/build/lib-client/3nstorage/util/for-arrays.js +32 -0
- package/build/lib-client/3nstorage/xsp-fs/common.d.ts +5 -4
- package/build/lib-client/3nstorage/xsp-fs/common.js +1 -0
- package/build/lib-client/3nstorage/xsp-fs/file-node.d.ts +5 -10
- package/build/lib-client/3nstorage/xsp-fs/file-node.js +43 -45
- package/build/lib-client/3nstorage/xsp-fs/file.d.ts +7 -6
- package/build/lib-client/3nstorage/xsp-fs/file.js +14 -20
- package/build/lib-client/3nstorage/xsp-fs/folder-node.d.ts +16 -5
- package/build/lib-client/3nstorage/xsp-fs/folder-node.js +238 -68
- package/build/lib-client/3nstorage/xsp-fs/fs.d.ts +18 -17
- package/build/lib-client/3nstorage/xsp-fs/fs.js +32 -37
- package/build/lib-client/3nstorage/xsp-fs/node-in-fs.d.ts +15 -11
- package/build/lib-client/3nstorage/xsp-fs/node-in-fs.js +72 -22
- package/build/lib-client/3nstorage/xsp-fs/xsp-payload-v1.js +1 -1
- package/build/lib-client/local-files/device-fs.js +11 -11
- package/build/lib-client/objs-on-disk/obj-on-disk.d.ts +5 -2
- package/build/lib-client/objs-on-disk/obj-on-disk.js +16 -1
- package/build/lib-client/user-with-mid-session.d.ts +2 -1
- package/build/lib-client/user-with-mid-session.js +7 -1
- package/build/lib-common/async-fs-node.js +8 -8
- package/build/lib-common/exceptions/file.d.ts +4 -2
- package/build/lib-common/exceptions/file.js +24 -58
- package/build/lib-common/ipc/generic-ipc.js +5 -4
- package/build/lib-common/objs-on-disk/file-layout.js +1 -1
- package/build/lib-common/objs-on-disk/utils.js +1 -1
- package/build/lib-common/service-api/3nstorage/owner.d.ts +8 -9
- package/build/lib-common/service-api/3nstorage/owner.js +2 -1
- package/build/protos/asmail.proto.js +5943 -4348
- package/build/protos/file.proto.js +874 -0
- package/build/protos/fs.proto.js +7014 -5419
- package/package.json +3 -2
- package/protos/file.proto +23 -7
- package/protos/fs.proto +27 -13
- 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)(
|
|
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)(
|
|
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
|
-
|
|
256
|
-
|
|
257
|
-
|
|
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)(
|
|
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)(
|
|
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)(
|
|
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)(
|
|
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
|
-
|
|
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
|
|
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)(
|
|
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)(
|
|
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)(
|
|
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):
|
|
36
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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)(
|
|
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
|
-
|
|
139
|
-
|
|
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)(
|
|
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)(
|
|
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)(
|
|
228
|
+
throw (0, file_1.makeFileException)('concurrentUpdate', this.name, exc);
|
|
191
229
|
}
|
|
192
230
|
else if (exc.objNotFound) {
|
|
193
|
-
throw (0, file_1.makeFileException)(
|
|
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)(
|
|
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
|
|
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 = (
|
|
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)(
|
|
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)(
|
|
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)(
|
|
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)(
|
|
230
|
+
throw (0, file_1.makeFileException)('alreadyExists', root);
|
|
231
231
|
}
|
|
232
232
|
if (!stat.isDirectory()) {
|
|
233
|
-
throw (0, file_1.makeFileException)(
|
|
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)(
|
|
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)(
|
|
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)(
|
|
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)(
|
|
695
|
+
throw (0, file_1.makeFileException)('alreadyExists', path);
|
|
696
696
|
}
|
|
697
697
|
if (!exists && !flags.create) {
|
|
698
|
-
throw (0, file_1.makeFileException)(
|
|
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.
|
|
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)(
|
|
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)
|
|
44
|
-
getSegs(objId: ObjId, version: number, start: number, end: number)
|
|
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 } :
|
|
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
|
|
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.
|