core-3nweb-client-lib 0.26.1 → 0.27.3
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/asmail.d.ts +1 -1
- package/build/api-defs/files.d.ts +281 -75
- package/build/core/app-files.js +7 -7
- package/build/core/asmail/config/common.js +2 -2
- package/build/core/asmail/config/index.js +2 -2
- package/build/core/asmail/config/published-intro-key.js +1 -1
- package/build/core/asmail/delivery/common.js +7 -7
- package/build/core/asmail/delivery/index.js +5 -5
- package/build/core/asmail/delivery/msg.js +4 -4
- package/build/core/asmail/delivery/per-recipient-wip.js +1 -1
- package/build/core/asmail/inbox/attachments/fs.d.ts +2 -1
- package/build/core/asmail/inbox/attachments/fs.js +9 -4
- package/build/core/asmail/inbox/cached-msgs.js +1 -1
- package/build/core/asmail/inbox/inbox-events.js +4 -4
- package/build/core/asmail/inbox/index.js +10 -10
- package/build/core/asmail/inbox/msg-downloader.js +1 -1
- package/build/core/asmail/inbox/msg-indexing.js +1 -1
- package/build/core/asmail/inbox/msg-on-disk.js +5 -5
- package/build/core/asmail/index.d.ts +3 -3
- package/build/core/asmail/index.js +13 -8
- package/build/core/asmail/key-verification.js +5 -5
- package/build/core/asmail/keyring/common.js +7 -6
- package/build/core/asmail/keyring/correspondent-keys.js +8 -7
- package/build/core/asmail/keyring/id-to-email-map.js +2 -1
- package/build/core/asmail/keyring/index.d.ts +7 -8
- package/build/core/asmail/keyring/index.js +15 -14
- package/build/core/asmail/keyring/keyring-storage.js +2 -1
- package/build/core/asmail/msg/opener.js +3 -3
- package/build/core/asmail/msg/packer.js +13 -13
- package/build/core/asmail/sending-params/own-params.js +2 -2
- package/build/core/asmail/sending-params/params-from-others.js +1 -1
- package/build/core/id-manager/index.d.ts +43 -0
- package/build/core/{id-manager.js → id-manager/index.js} +36 -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.d.ts +2 -1
- package/build/core/index.js +31 -33
- package/build/core/sign-in.d.ts +1 -2
- package/build/core/sign-in.js +8 -17
- package/build/core/sign-up.d.ts +2 -0
- package/build/core/sign-up.js +11 -10
- package/build/core/storage/common/json-saving.js +2 -2
- package/build/core/storage/common/obj-info-file.d.ts +12 -4
- package/build/core/storage/common/obj-info-file.js +66 -34
- package/build/core/storage/common/utils.d.ts +2 -0
- package/build/core/storage/common/utils.js +32 -0
- package/build/core/storage/index.d.ts +5 -17
- package/build/core/storage/index.js +78 -119
- package/build/core/storage/local/obj-files-gc.d.ts +2 -0
- package/build/core/storage/local/obj-files-gc.js +49 -37
- package/build/core/storage/local/obj-files.d.ts +4 -7
- package/build/core/storage/local/obj-files.js +7 -10
- package/build/core/storage/local/obj-status.d.ts +12 -6
- package/build/core/storage/local/obj-status.js +24 -9
- package/build/core/storage/local/storage.d.ts +10 -7
- package/build/core/storage/local/storage.js +29 -18
- package/build/core/storage/synced/downloader.js +1 -1
- package/build/core/storage/synced/obj-files-gc.d.ts +1 -0
- package/build/core/storage/synced/obj-files-gc.js +76 -39
- package/build/core/storage/synced/obj-files.d.ts +50 -36
- package/build/core/storage/synced/obj-files.js +201 -162
- package/build/core/storage/synced/obj-status.d.ts +99 -86
- package/build/core/storage/synced/obj-status.js +520 -251
- package/build/core/storage/synced/remote-events.d.ts +11 -12
- package/build/core/storage/synced/remote-events.js +73 -56
- package/build/core/storage/synced/storage.d.ts +24 -10
- package/build/core/storage/synced/storage.js +147 -47
- package/build/core/storage/synced/upload-header-file.d.ts +4 -0
- package/build/core/storage/synced/upload-header-file.js +64 -0
- package/build/core/storage/synced/upsyncer.d.ts +12 -7
- package/build/core/storage/synced/upsyncer.js +210 -280
- package/build/core/storage/system-folders/apps-data.d.ts +16 -0
- package/build/core/storage/system-folders/apps-data.js +110 -0
- package/build/core/storage/system-folders/index.d.ts +18 -0
- package/build/core/storage/system-folders/index.js +77 -0
- package/build/core-ipc/common-caps.js +3 -3
- package/build/core-ipc/generic.js +8 -8
- package/build/core-ipc/startup-caps.js +2 -2
- package/build/cryptors.js +6 -2
- package/build/ipc-via-protobuf/asmail-cap.js +58 -57
- package/build/ipc-via-protobuf/bytes.js +16 -17
- package/build/ipc-via-protobuf/connector-clients-side.d.ts +1 -0
- package/build/ipc-via-protobuf/connector-clients-side.js +14 -15
- package/build/ipc-via-protobuf/connector-services-side.js +10 -10
- package/build/ipc-via-protobuf/connector.js +4 -4
- package/build/ipc-via-protobuf/file.d.ts +48 -12
- package/build/ipc-via-protobuf/file.js +474 -126
- package/build/ipc-via-protobuf/fs.d.ts +8 -0
- package/build/ipc-via-protobuf/fs.js +577 -142
- package/build/ipc-via-protobuf/log-cap.js +2 -2
- package/build/ipc-via-protobuf/mailerid.js +3 -3
- package/build/ipc-via-protobuf/protobuf-msg.d.ts +1 -0
- package/build/ipc-via-protobuf/protobuf-msg.js +11 -7
- package/build/ipc-via-protobuf/startup-cap.js +21 -21
- package/build/ipc-via-protobuf/storage-cap.js +12 -12
- package/build/ipc.js +7 -2
- package/build/lib-client/3nstorage/exceptions.d.ts +16 -1
- package/build/lib-client/3nstorage/exceptions.js +21 -3
- package/build/lib-client/3nstorage/service.d.ts +21 -3
- package/build/lib-client/3nstorage/service.js +128 -46
- package/build/lib-client/3nstorage/util/file-based-json.d.ts +2 -1
- package/build/lib-client/3nstorage/util/file-based-json.js +3 -2
- 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/attrs.js +17 -17
- package/build/lib-client/3nstorage/xsp-fs/common.d.ts +44 -19
- package/build/lib-client/3nstorage/xsp-fs/common.js +30 -19
- package/build/lib-client/3nstorage/xsp-fs/file-node.d.ts +1 -0
- package/build/lib-client/3nstorage/xsp-fs/file-node.js +17 -13
- package/build/lib-client/3nstorage/xsp-fs/file.d.ts +31 -6
- package/build/lib-client/3nstorage/xsp-fs/file.js +73 -25
- package/build/lib-client/3nstorage/xsp-fs/folder-node-serialization.js +4 -4
- package/build/lib-client/3nstorage/xsp-fs/folder-node.d.ts +32 -13
- package/build/lib-client/3nstorage/xsp-fs/folder-node.js +752 -192
- package/build/lib-client/3nstorage/xsp-fs/fs.d.ts +35 -4
- package/build/lib-client/3nstorage/xsp-fs/fs.js +236 -119
- package/build/lib-client/3nstorage/xsp-fs/link-node.d.ts +1 -0
- package/build/lib-client/3nstorage/xsp-fs/link-node.js +7 -2
- package/build/lib-client/3nstorage/xsp-fs/node-in-fs.d.ts +30 -29
- package/build/lib-client/3nstorage/xsp-fs/node-in-fs.js +232 -127
- package/build/lib-client/3nstorage/xsp-fs/node-persistence.d.ts +1 -1
- package/build/lib-client/3nstorage/xsp-fs/node-persistence.js +17 -18
- package/build/lib-client/3nstorage/xsp-fs/xsp-payload-v1.js +3 -3
- package/build/lib-client/3nstorage/xsp-fs/xsp-payload-v2.js +53 -53
- package/build/lib-client/3nweb-signup.js +4 -4
- package/build/lib-client/asmail/recipient.js +15 -15
- package/build/lib-client/asmail/sender.js +22 -22
- package/build/lib-client/asmail/service-config.js +3 -3
- package/build/lib-client/cryptor/cryptor-in-worker.js +18 -16
- package/build/lib-client/cryptor/cryptor-wasm.js +1 -1
- package/build/lib-client/cryptor/cryptor.js +4 -2
- package/build/lib-client/cryptor/cryptor.wasm +0 -0
- package/build/lib-client/cryptor/in-proc-js.js +1 -1
- package/build/lib-client/cryptor/in-proc-wasm.js +6 -6
- package/build/lib-client/cryptor/worker-js.js +2 -2
- package/build/lib-client/cryptor/worker-wasm.js +2 -2
- package/build/lib-client/files-select.js +1 -1
- package/build/lib-client/files.d.ts +1 -1
- package/build/lib-client/files.js +71 -6
- package/build/lib-client/fs-collection.js +1 -1
- package/build/lib-client/fs-sync-utils.d.ts +5 -0
- package/build/lib-client/fs-sync-utils.js +61 -0
- package/build/lib-client/fs-view.d.ts +14 -0
- package/build/lib-client/fs-view.js +33 -0
- package/build/lib-client/key-derivation.js +1 -1
- package/build/lib-client/local-files/dev-file-sink.js +9 -9
- package/build/lib-client/local-files/dev-file-src.js +2 -2
- package/build/lib-client/local-files/device-fs.d.ts +1 -1
- package/build/lib-client/local-files/device-fs.js +56 -54
- package/build/lib-client/logging/log-to-file.d.ts +1 -1
- package/build/lib-client/logging/log-to-file.js +7 -7
- package/build/lib-client/mailer-id/login.js +7 -7
- package/build/lib-client/mailer-id/provisioner.js +12 -12
- package/build/lib-client/objs-on-disk/file-writing-proc.js +3 -3
- package/build/lib-client/objs-on-disk/obj-folders.js +31 -31
- package/build/lib-client/objs-on-disk/obj-on-disk.d.ts +13 -2
- package/build/lib-client/objs-on-disk/obj-on-disk.js +24 -9
- package/build/lib-client/request-utils.d.ts +1 -0
- package/build/lib-client/request-utils.js +13 -13
- package/build/lib-client/server-events.d.ts +3 -3
- package/build/lib-client/server-events.js +9 -8
- package/build/lib-client/service-locator.js +10 -10
- package/build/lib-client/user-with-mid-session.d.ts +2 -1
- package/build/lib-client/user-with-mid-session.js +14 -8
- package/build/lib-client/user-with-pkl-session.js +25 -25
- package/build/lib-client/ws-utils.js +2 -2
- package/build/lib-common/async-cryptor-wrap.js +4 -4
- package/build/lib-common/async-fs-node.d.ts +5 -3
- package/build/lib-common/async-fs-node.js +17 -17
- package/build/lib-common/byte-streaming/pipe.js +1 -1
- package/build/lib-common/byte-streaming/wrapping.js +13 -13
- package/build/lib-common/canonical-address.js +1 -1
- package/build/lib-common/exceptions/error.d.ts +1 -0
- package/build/lib-common/exceptions/error.js +7 -6
- package/build/lib-common/exceptions/file.d.ts +4 -2
- package/build/lib-common/exceptions/file.js +24 -54
- package/build/lib-common/ipc/generic-ipc.js +5 -4
- package/build/lib-common/ipc/ws-ipc.js +2 -2
- package/build/lib-common/mid-sigs-NaCl-Ed.js +14 -14
- package/build/lib-common/objs-on-disk/file-layout.d.ts +19 -0
- package/build/lib-common/objs-on-disk/file-layout.js +130 -12
- package/build/lib-common/objs-on-disk/obj-file.d.ts +13 -2
- package/build/lib-common/objs-on-disk/obj-file.js +96 -35
- package/build/lib-common/objs-on-disk/utils.d.ts +1 -0
- package/build/lib-common/objs-on-disk/utils.js +3 -3
- package/build/lib-common/objs-on-disk/v1-obj-file-format.js +14 -14
- package/build/lib-common/processes/labelled-exec-pools.d.ts +1 -1
- package/build/lib-common/processes/labelled-exec-pools.js +1 -1
- package/build/lib-common/processes/pressure.js +2 -2
- package/build/lib-common/processes/synced.js +1 -1
- package/build/lib-common/processes/timeout.js +2 -2
- package/build/lib-common/random-node.js +7 -7
- package/build/lib-common/service-api/3nstorage/owner.d.ts +101 -42
- package/build/lib-common/service-api/3nstorage/owner.js +83 -40
- package/build/lib-common/service-api/asmail/delivery.js +2 -2
- package/build/lib-common/service-api/asmail/retrieval.js +1 -1
- package/build/lib-common/timed-cache.d.ts +1 -0
- package/build/lib-common/timed-non-weak-cache.d.ts +1 -0
- package/build/lib-common/timed-non-weak-cache.js +11 -0
- package/build/lib-common/utils-for-observables.js +4 -4
- package/build/lib-common/weak-cache.d.ts +1 -0
- package/build/lib-common/weak-cache.js +12 -1
- package/build/lib-index.d.ts +2 -1
- package/build/lib-index.js +10 -7
- package/build/protos/asmail.proto.js +12955 -7496
- package/build/protos/file.proto.js +4867 -2744
- package/build/protos/fs.proto.js +9227 -3768
- package/package.json +7 -5
- package/protos/file.proto +91 -19
- package/protos/fs.proto +107 -8
- package/build/core/id-manager.d.ts +0 -46
|
@@ -16,30 +16,37 @@
|
|
|
16
16
|
this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
17
|
*/
|
|
18
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
-
exports.SyncedObj = exports.ObjFiles = void 0;
|
|
19
|
+
exports.SyncedObj = exports.ObjFiles = exports.REMOTE_FILE_NAME_EXT = exports.UNSYNCED_FILE_NAME_EXT = void 0;
|
|
20
20
|
const rxjs_1 = require("rxjs");
|
|
21
21
|
const synced_1 = require("../../../lib-common/processes/synced");
|
|
22
|
-
const sleep_1 = require("../../../lib-common/processes/sleep");
|
|
23
22
|
const obj_folders_1 = require("../../../lib-client/objs-on-disk/obj-folders");
|
|
24
23
|
const fs = require("../../../lib-common/async-fs-node");
|
|
25
24
|
const obj_on_disk_1 = require("../../../lib-client/objs-on-disk/obj-on-disk");
|
|
26
25
|
const path_1 = require("path");
|
|
26
|
+
const downloader_1 = require("./downloader");
|
|
27
27
|
const assert_1 = require("../../../lib-common/assert");
|
|
28
28
|
const operators_1 = require("rxjs/operators");
|
|
29
29
|
const utils_for_observables_1 = require("../../../lib-common/utils-for-observables");
|
|
30
30
|
const obj_files_gc_1 = require("./obj-files-gc");
|
|
31
31
|
const obj_status_1 = require("./obj-status");
|
|
32
32
|
const timed_cache_1 = require("../../../lib-common/timed-cache");
|
|
33
|
-
const
|
|
34
|
-
const
|
|
35
|
-
|
|
33
|
+
const upload_header_file_1 = require("./upload-header-file");
|
|
34
|
+
const utils_1 = require("../common/utils");
|
|
35
|
+
exports.UNSYNCED_FILE_NAME_EXT = 'unsynced';
|
|
36
|
+
exports.REMOTE_FILE_NAME_EXT = 'v';
|
|
37
|
+
/**
|
|
38
|
+
* File system has nodes. Each node may have data in one or many objects of
|
|
39
|
+
* storage. SyncedObj allows to work with files of storage object, even when
|
|
40
|
+
* file system node no longer exists. ObjFiles is a holder and factory of
|
|
41
|
+
* SyncedObj's.
|
|
42
|
+
*/
|
|
36
43
|
class ObjFiles {
|
|
37
|
-
constructor(folders,
|
|
44
|
+
constructor(folders, remote, logError) {
|
|
38
45
|
this.folders = folders;
|
|
39
|
-
this.downloader = downloader;
|
|
40
46
|
this.logError = logError;
|
|
41
|
-
this.objs = timed_cache_1.makeTimedCache(60 * 1000);
|
|
47
|
+
this.objs = (0, timed_cache_1.makeTimedCache)(60 * 1000);
|
|
42
48
|
this.sync = makeSynchronizer();
|
|
49
|
+
this.downloader = new downloader_1.Downloader(remote);
|
|
43
50
|
this.gc = new obj_files_gc_1.GC(this.sync, obj => {
|
|
44
51
|
if (this.objs.get(obj.objId) === obj) {
|
|
45
52
|
this.objs.delete(obj.objId);
|
|
@@ -47,29 +54,28 @@ class ObjFiles {
|
|
|
47
54
|
}, objId => this.folders.removeFolderOf(objId));
|
|
48
55
|
Object.freeze(this);
|
|
49
56
|
}
|
|
50
|
-
static async makeFor(path,
|
|
51
|
-
const
|
|
52
|
-
|
|
57
|
+
static async makeFor(path, remote, logError) {
|
|
58
|
+
const canMove = (objId, objFolderPath) => objFiles.canMoveObjToDeeperCache(objId, objFolderPath);
|
|
59
|
+
const folders = await obj_folders_1.ObjFolders.makeWithGenerations(path, canMove, logError);
|
|
60
|
+
const objFiles = new ObjFiles(folders, remote, logError);
|
|
61
|
+
return objFiles;
|
|
62
|
+
}
|
|
63
|
+
async canMoveObjToDeeperCache(objId, objFolderPath) {
|
|
64
|
+
if (this.objs.has(objId)) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
const lst = await fs.readdir(objFolderPath);
|
|
68
|
+
for (const fName of lst) {
|
|
69
|
+
if (fName.endsWith(exports.UNSYNCED_FILE_NAME_EXT)) {
|
|
53
70
|
return false;
|
|
54
71
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
const status = await obj_status_1.readAndCheckStatus(objFolderPath, objId).catch(noop);
|
|
63
|
-
if (status && status.syncTasks) {
|
|
64
|
-
return false;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
return true;
|
|
70
|
-
}, logError);
|
|
71
|
-
const objFiles = new ObjFiles(folders, downloader, logError);
|
|
72
|
-
return objFiles;
|
|
72
|
+
}
|
|
73
|
+
try {
|
|
74
|
+
return (await obj_status_1.ObjStatus.fileShowsObjNotInSyncedState(objFolderPath, objId));
|
|
75
|
+
}
|
|
76
|
+
catch (exc) {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
73
79
|
}
|
|
74
80
|
async findObj(objId) {
|
|
75
81
|
let obj = this.objs.get(objId);
|
|
@@ -86,12 +92,15 @@ class ObjFiles {
|
|
|
86
92
|
return obj;
|
|
87
93
|
});
|
|
88
94
|
}
|
|
95
|
+
getObjInCache(objId) {
|
|
96
|
+
return this.objs.get(objId);
|
|
97
|
+
}
|
|
89
98
|
makeObj(objId, download) {
|
|
90
99
|
return this.sync(objId, async () => {
|
|
91
100
|
const folder = await this.folders.getFolderAccessFor(objId, true);
|
|
92
101
|
let obj;
|
|
93
102
|
if (download) {
|
|
94
|
-
assert_1.assert(typeof download.version === 'number');
|
|
103
|
+
(0, assert_1.assert)(typeof download.version === 'number');
|
|
95
104
|
obj = await SyncedObj.forDownloadedObj(objId, folder, this.downloader, this.gc.scheduleCollection, download.version, download.parts, this.logError);
|
|
96
105
|
}
|
|
97
106
|
else {
|
|
@@ -112,6 +121,10 @@ class ObjFiles {
|
|
|
112
121
|
return;
|
|
113
122
|
});
|
|
114
123
|
}
|
|
124
|
+
// XXX we'll need getting archived version.
|
|
125
|
+
// Getting current may be changed to grub info about all obj versions.
|
|
126
|
+
// As currently this.makeByDownloadingCurrentVersion() makes assumptions.
|
|
127
|
+
// Should it be a pattern: version not in status -> get info first.
|
|
115
128
|
async makeByDownloadingCurrentVersion(objId) {
|
|
116
129
|
// initial download implicitly checks existence of obj on server
|
|
117
130
|
const download = await this.downloader.getCurrentObjVersion(objId);
|
|
@@ -121,28 +134,29 @@ class ObjFiles {
|
|
|
121
134
|
async saveFirstVersion(objId, encSub) {
|
|
122
135
|
const newObj = await this.makeObj(objId);
|
|
123
136
|
const fileWrite$ = (await newObj.saveNewVersion(1, encSub)).fileWrite$
|
|
124
|
-
.pipe(utils_for_observables_1.flatTap(undefined, err => this.removeFailedNewObj(newObj)));
|
|
137
|
+
.pipe((0, utils_for_observables_1.flatTap)(undefined, err => this.removeFailedNewObj(newObj)));
|
|
125
138
|
return { fileWrite$, newObj };
|
|
126
139
|
}
|
|
127
|
-
|
|
128
|
-
return rxjs_1.from([undefined])
|
|
140
|
+
findObjsToRemoveOnRemote() {
|
|
141
|
+
return (0, rxjs_1.from)([undefined])
|
|
129
142
|
.pipe(
|
|
130
143
|
// listing recent folders, exactly once
|
|
131
|
-
operators_1.mergeMap(() => this.folders.listRecent()),
|
|
144
|
+
(0, operators_1.mergeMap)(() => this.folders.listRecent()),
|
|
132
145
|
// flatten array and space it in time, to process folders one by one
|
|
133
|
-
operators_1.mergeMap(objsAndPaths => objsAndPaths), operators_1.
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
operators_1.mergeMap(({ path, objId }) => this.sync(objId, async () => {
|
|
139
|
-
if (this.objs.has(objId)) {
|
|
140
|
-
return;
|
|
146
|
+
(0, operators_1.mergeMap)(objsAndPaths => objsAndPaths), (0, operators_1.mergeMap)(async ({ objId, path }) => {
|
|
147
|
+
const obj = this.objs.get(objId);
|
|
148
|
+
if (obj) {
|
|
149
|
+
return (obj.statusObj().needsRemovalOnRemote() ?
|
|
150
|
+
objId : undefined);
|
|
141
151
|
}
|
|
142
|
-
|
|
143
|
-
.
|
|
144
|
-
|
|
145
|
-
|
|
152
|
+
else {
|
|
153
|
+
const needsRm = await obj_status_1.ObjStatus.fileShowsObjNeedsRemovalOnRemote(path, objId);
|
|
154
|
+
return (needsRm ? objId : undefined);
|
|
155
|
+
}
|
|
156
|
+
}, 1), (0, operators_1.filter)(objId => (objId !== undefined)));
|
|
157
|
+
}
|
|
158
|
+
scheduleGC(obj) {
|
|
159
|
+
this.gc.scheduleCollection(obj);
|
|
146
160
|
}
|
|
147
161
|
}
|
|
148
162
|
exports.ObjFiles = ObjFiles;
|
|
@@ -175,47 +189,26 @@ class SyncedObj {
|
|
|
175
189
|
this.status = status;
|
|
176
190
|
this.downloader = downloader;
|
|
177
191
|
this.scheduleGC = scheduleGC;
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
* These are conflicting versions, coming from a server. Of course, universal
|
|
185
|
-
* truth is spread by server, but in situations of parallel changes, local
|
|
186
|
-
* version allows things to work, while conflicting version from server
|
|
187
|
-
* should be adopted by conflict resolution process. In other words, these
|
|
188
|
-
* versions are not for common use.
|
|
189
|
-
*/
|
|
190
|
-
this.remoteConflictVerObjs = timed_cache_1.makeTimedCache(60 * 1000);
|
|
191
|
-
this.objSegsGetterFromDisk = async (ver, ofs, len) => {
|
|
192
|
-
let obj = this.verObjs.get(ver);
|
|
193
|
-
if (!obj) {
|
|
194
|
-
const fPath = this.path(ver, this.status.isVersionSynced(ver));
|
|
195
|
-
try {
|
|
196
|
-
obj = await obj_on_disk_1.ObjOnDisk.forExistingFile(this.objId, ver, fPath, this.downloader, this.objSegsGetterFromDisk);
|
|
197
|
-
this.verObjs.set(ver, obj);
|
|
198
|
-
}
|
|
199
|
-
catch (exc) {
|
|
200
|
-
// when file doesn't exist on a disk, we just pass a chunk
|
|
201
|
-
if (!exc.notFound) {
|
|
202
|
-
throw exc;
|
|
203
|
-
}
|
|
204
|
-
return [{ type: 'new', thisVerOfs: ofs, len }];
|
|
205
|
-
}
|
|
192
|
+
this.remoteVers = (0, timed_cache_1.makeTimedCache)(60 * 1000);
|
|
193
|
+
this.localVers = (0, timed_cache_1.makeTimedCache)(60 * 1000);
|
|
194
|
+
this.localAndSyncedObjSegsGetterFromDisk = async (v, ofs, len) => {
|
|
195
|
+
const latestSynced = this.status.latestSyncedVersion();
|
|
196
|
+
if (latestSynced && (latestSynced >= v)) {
|
|
197
|
+
return this.remoteObjSegsGetterFromDisk(v, ofs, len);
|
|
206
198
|
}
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
return this.objSegsGetterFromDisk(version, ofs, len);
|
|
199
|
+
let objVer = this.localVers.get(v);
|
|
200
|
+
if (!objVer) {
|
|
201
|
+
objVer = await obj_on_disk_1.ObjOnDisk.forExistingFile(this.objId, v, this.localVerPath(v), this.downloader, this.localAndSyncedObjSegsGetterFromDisk);
|
|
202
|
+
this.localVers.set(v, objVer);
|
|
212
203
|
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
204
|
+
return objVer.readSegsOnlyFromDisk(ofs, len);
|
|
205
|
+
};
|
|
206
|
+
this.remoteObjSegsGetterFromDisk = async (v, ofs, len) => {
|
|
207
|
+
let objVer = this.remoteVers.get(v);
|
|
208
|
+
if (!objVer) {
|
|
216
209
|
try {
|
|
217
|
-
|
|
218
|
-
this.
|
|
210
|
+
objVer = await obj_on_disk_1.ObjOnDisk.forExistingFile(this.objId, v, this.remoteVerPath(v), this.downloader, this.remoteObjSegsGetterFromDisk);
|
|
211
|
+
this.remoteVers.set(v, objVer);
|
|
219
212
|
}
|
|
220
213
|
catch (exc) {
|
|
221
214
|
// when file doesn't exist on a disk, we just pass a chunk
|
|
@@ -225,7 +218,7 @@ class SyncedObj {
|
|
|
225
218
|
return [{ type: 'new', thisVerOfs: ofs, len }];
|
|
226
219
|
}
|
|
227
220
|
}
|
|
228
|
-
return
|
|
221
|
+
return objVer.readSegsOnlyFromDisk(ofs, len);
|
|
229
222
|
};
|
|
230
223
|
Object.freeze(this);
|
|
231
224
|
}
|
|
@@ -234,126 +227,173 @@ class SyncedObj {
|
|
|
234
227
|
return new SyncedObj(objId, objFolder, status, downloader, scheduleGC);
|
|
235
228
|
}
|
|
236
229
|
static async forDownloadedObj(objId, objFolder, downloader, scheduleGC, version, parts, logError) {
|
|
237
|
-
// XXX let's note that given version is
|
|
230
|
+
// XXX let's note that given version is also passed as current on server
|
|
238
231
|
const status = await obj_status_1.ObjStatus.makeForDownloadedVersion(objFolder, objId, version, version, logError);
|
|
239
232
|
const obj = new SyncedObj(objId, objFolder, status, downloader, scheduleGC);
|
|
240
|
-
const fPath = obj.
|
|
241
|
-
const objVer = await obj_on_disk_1.ObjOnDisk.createFileForExistingVersion(obj.objId, version, fPath, obj.downloader, obj.
|
|
242
|
-
obj.
|
|
233
|
+
const fPath = obj.remoteVerPath(version);
|
|
234
|
+
const objVer = await obj_on_disk_1.ObjOnDisk.createFileForExistingVersion(obj.objId, version, fPath, obj.downloader, obj.remoteObjSegsGetterFromDisk, parts);
|
|
235
|
+
obj.remoteVers.set(version, objVer);
|
|
243
236
|
return obj;
|
|
244
237
|
}
|
|
245
238
|
static async forNewObj(objId, objFolder, downloader, scheduleGC, logError) {
|
|
246
239
|
const status = await obj_status_1.ObjStatus.makeNew(objFolder, objId, logError);
|
|
247
240
|
return new SyncedObj(objId, objFolder, status, downloader, scheduleGC);
|
|
248
241
|
}
|
|
249
|
-
sync() {
|
|
250
|
-
return this.status;
|
|
251
|
-
}
|
|
252
242
|
scheduleSelfGC() {
|
|
253
243
|
this.scheduleGC(this);
|
|
254
244
|
}
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
SYNCED_FILE_NAME_EXT :
|
|
258
|
-
(remote ? REMOTE_FILE_NAME_EXT : UNSYNCED_FILE_NAME_EXT));
|
|
259
|
-
const fName = `${version}.${fileExt}`;
|
|
260
|
-
return path_1.join(this.objFolder, fName);
|
|
245
|
+
localVerPath(version) {
|
|
246
|
+
return (0, path_1.join)(this.objFolder, `${version}.${exports.UNSYNCED_FILE_NAME_EXT}`);
|
|
261
247
|
}
|
|
262
|
-
|
|
263
|
-
|
|
248
|
+
remoteVerPath(version) {
|
|
249
|
+
return (0, path_1.join)(this.objFolder, `${version}.${exports.REMOTE_FILE_NAME_EXT}`);
|
|
250
|
+
}
|
|
251
|
+
async getObjSrcFromLocalAndSyncedBranch(version) {
|
|
252
|
+
const latestSynced = this.status.latestSyncedVersion();
|
|
253
|
+
const objVer = await ((latestSynced && (latestSynced >= version)) ?
|
|
254
|
+
this.instanceOfRemoteObjVer(version) :
|
|
255
|
+
this.instanceOfLocalObjVer(version));
|
|
256
|
+
return objVer.getSrc();
|
|
257
|
+
}
|
|
258
|
+
async getObjSrcFromRemoteAndSyncedBranch(version) {
|
|
259
|
+
const objVer = await this.instanceOfRemoteObjVer(version);
|
|
260
|
+
return objVer.getSrc();
|
|
261
|
+
}
|
|
262
|
+
async instanceOfLocalObjVer(version) {
|
|
263
|
+
let objVer = this.localVers.get(version);
|
|
264
264
|
if (objVer) {
|
|
265
|
-
return objVer
|
|
266
|
-
}
|
|
267
|
-
const isSynced = this.status.isVersionSynced(version);
|
|
268
|
-
const fPath = this.path(version, isSynced);
|
|
269
|
-
if (isSynced) {
|
|
270
|
-
objVer = ((await isOnDisk(fPath)) ?
|
|
271
|
-
await obj_on_disk_1.ObjOnDisk.forExistingFile(this.objId, version, fPath, this.downloader, this.objSegsGetterFromDisk) :
|
|
272
|
-
await obj_on_disk_1.ObjOnDisk.createFileForExistingVersion(this.objId, version, fPath, this.downloader, this.objSegsGetterFromDisk));
|
|
265
|
+
return objVer;
|
|
273
266
|
}
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
this.verObjs.set(version, objVer);
|
|
279
|
-
return src;
|
|
267
|
+
const fPath = this.localVerPath(version);
|
|
268
|
+
objVer = await obj_on_disk_1.ObjOnDisk.forExistingFile(this.objId, version, fPath, this.downloader, this.localAndSyncedObjSegsGetterFromDisk);
|
|
269
|
+
this.localVers.set(version, objVer);
|
|
270
|
+
return objVer;
|
|
280
271
|
}
|
|
281
|
-
async
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
let obj = this.remoteConflictVerObjs.get(version);
|
|
286
|
-
if (obj) {
|
|
287
|
-
return obj.getSrc();
|
|
272
|
+
async instanceOfRemoteObjVer(version) {
|
|
273
|
+
let objVer = this.remoteVers.get(version);
|
|
274
|
+
if (objVer) {
|
|
275
|
+
return objVer;
|
|
288
276
|
}
|
|
289
|
-
const fPath = this.
|
|
290
|
-
|
|
291
|
-
await obj_on_disk_1.ObjOnDisk.forExistingFile(this.objId, version, fPath, this.downloader, this.
|
|
292
|
-
await obj_on_disk_1.ObjOnDisk.createFileForExistingVersion(this.objId, version, fPath, this.downloader, this.
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
return src;
|
|
277
|
+
const fPath = this.remoteVerPath(version);
|
|
278
|
+
objVer = ((await isOnDisk(fPath)) ?
|
|
279
|
+
await obj_on_disk_1.ObjOnDisk.forExistingFile(this.objId, version, fPath, this.downloader, this.remoteObjSegsGetterFromDisk) :
|
|
280
|
+
await obj_on_disk_1.ObjOnDisk.createFileForExistingVersion(this.objId, version, fPath, this.downloader, this.remoteObjSegsGetterFromDisk));
|
|
281
|
+
this.remoteVers.set(version, objVer);
|
|
282
|
+
return objVer;
|
|
296
283
|
}
|
|
297
284
|
async saveNewVersion(version, encSub) {
|
|
298
|
-
if (this.
|
|
285
|
+
if (this.localVers.has(version)) {
|
|
299
286
|
throw new Error(`Version ${version} already exists in object ${this.objId}`);
|
|
300
287
|
}
|
|
301
|
-
const fPath = this.
|
|
302
|
-
const { obj, write$ } = await obj_on_disk_1.ObjOnDisk.createFileForWriteOfNewVersion(this.objId, version, fPath, encSub, this.downloader, this.
|
|
303
|
-
this.
|
|
304
|
-
const fileWrite$ = write$.pipe(operators_1.tap({
|
|
288
|
+
const fPath = this.localVerPath(version);
|
|
289
|
+
const { obj, write$ } = await obj_on_disk_1.ObjOnDisk.createFileForWriteOfNewVersion(this.objId, version, fPath, encSub, this.downloader, this.localAndSyncedObjSegsGetterFromDisk);
|
|
290
|
+
this.localVers.set(version, obj);
|
|
291
|
+
const fileWrite$ = write$.pipe((0, operators_1.tap)({
|
|
305
292
|
error: err => {
|
|
306
|
-
if (this.
|
|
307
|
-
this.
|
|
293
|
+
if (this.localVers.get(version) === obj) {
|
|
294
|
+
this.localVers.delete(version);
|
|
308
295
|
}
|
|
309
296
|
}
|
|
310
|
-
}), utils_for_observables_1.flatTap(undefined, undefined, () => this.setUnsyncedCurrentVersion(version, obj.getBaseVersion())));
|
|
297
|
+
}), (0, utils_for_observables_1.flatTap)(undefined, undefined, () => this.setUnsyncedCurrentVersion(version, obj.getBaseVersion())));
|
|
311
298
|
return { fileWrite$, baseVer: obj.getBaseVersion() };
|
|
312
299
|
}
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
300
|
+
async combineLocalBaseIfPresent(version) {
|
|
301
|
+
const bases = this.status.baseOfLocalVersion(version);
|
|
302
|
+
if (!bases) {
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
const { localBases, syncedBase } = bases;
|
|
306
|
+
if (localBases) {
|
|
307
|
+
const objVer = await this.instanceOfLocalObjVer(version);
|
|
308
|
+
for (const localBase of localBases) {
|
|
309
|
+
await objVer.absorbImmediateBaseVersion(localBase, this.localVerPath(localBase));
|
|
310
|
+
this.status.absorbLocalVersionBase(version, localBase);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
return syncedBase;
|
|
321
314
|
}
|
|
322
|
-
|
|
323
|
-
|
|
315
|
+
async saveUploadHeaderFile(uploadHeader) {
|
|
316
|
+
await (0, upload_header_file_1.saveUploadHeaderFile)(this.objFolder, uploadHeader);
|
|
324
317
|
}
|
|
325
318
|
async setUnsyncedCurrentVersion(version, baseVersion) {
|
|
326
|
-
await this.status.
|
|
319
|
+
await this.status.setLocalCurrentVersion(version, baseVersion);
|
|
327
320
|
if (version > 1) {
|
|
328
321
|
this.scheduleSelfGC();
|
|
329
322
|
}
|
|
330
323
|
}
|
|
331
|
-
|
|
332
|
-
|
|
324
|
+
/**
|
|
325
|
+
* This renames/moves version file from local to remote.
|
|
326
|
+
* Removes upload info from status, updating enumerations of local and
|
|
327
|
+
* synced versions.
|
|
328
|
+
*/
|
|
329
|
+
async recordUploadCompletion(localVersion, uploadVersion, headerChange) {
|
|
330
|
+
const verObj = this.localVers.get(localVersion);
|
|
331
|
+
const remotePath = this.remoteVerPath(uploadVersion);
|
|
333
332
|
if (verObj) {
|
|
334
|
-
await verObj.
|
|
333
|
+
const syncedVerObj = await verObj.moveFileAndProxyThis(remotePath, (headerChange ? {
|
|
334
|
+
newHeader: headerChange.newHeader,
|
|
335
|
+
originalHeader: headerChange.originalHeader,
|
|
336
|
+
version: uploadVersion
|
|
337
|
+
} : undefined));
|
|
338
|
+
this.remoteVers.set(uploadVersion, syncedVerObj);
|
|
335
339
|
}
|
|
336
340
|
else {
|
|
337
|
-
await fs.rename(this.
|
|
341
|
+
await fs.rename(this.localVerPath(localVersion), remotePath);
|
|
338
342
|
}
|
|
339
|
-
await this.status.
|
|
343
|
+
await this.status.recordUploadCompletion(localVersion, uploadVersion);
|
|
340
344
|
this.scheduleSelfGC();
|
|
341
345
|
}
|
|
342
|
-
|
|
343
|
-
|
|
346
|
+
dropCachedLocalObjVersionsLessOrEqual(version) {
|
|
347
|
+
for (const version of this.localVers.keys()) {
|
|
348
|
+
if (version <= version) {
|
|
349
|
+
this.localVers.delete(version);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
344
352
|
}
|
|
345
|
-
async
|
|
346
|
-
await this.
|
|
353
|
+
async removeLocalVersionFilesLessThan(version) {
|
|
354
|
+
const lst = await fs.readdir(this.objFolder).catch(utils_1.noop);
|
|
355
|
+
if (!lst) {
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
const rmProcs = [];
|
|
359
|
+
for (const f of lst) {
|
|
360
|
+
if (!f.endsWith(exports.UNSYNCED_FILE_NAME_EXT)) {
|
|
361
|
+
continue;
|
|
362
|
+
}
|
|
363
|
+
const verStr = f.slice(0, f.length - 1 - exports.UNSYNCED_FILE_NAME_EXT.length);
|
|
364
|
+
const ver = parseInt(verStr);
|
|
365
|
+
if (isNaN(ver) || (ver > version)) {
|
|
366
|
+
continue;
|
|
367
|
+
}
|
|
368
|
+
rmProcs.push(fs.unlink((0, path_1.join)(this.objFolder, f)).catch(utils_1.noop));
|
|
369
|
+
}
|
|
370
|
+
if (rmProcs.length > 0) {
|
|
371
|
+
await Promise.all(rmProcs);
|
|
372
|
+
}
|
|
347
373
|
}
|
|
348
374
|
async removeCurrentVersion() {
|
|
349
|
-
await this.status.removeCurrentVersion(
|
|
375
|
+
await this.status.removeCurrentVersion();
|
|
376
|
+
// note that gc is tasked with removing current obj version on server
|
|
350
377
|
this.scheduleSelfGC();
|
|
351
378
|
}
|
|
352
|
-
|
|
353
|
-
|
|
379
|
+
async diffForUploadOf(version) {
|
|
380
|
+
const objVer = await this.instanceOfLocalObjVer(version);
|
|
381
|
+
if (objVer.getBaseVersion()) {
|
|
382
|
+
return objVer.diffFromBase();
|
|
383
|
+
}
|
|
384
|
+
else {
|
|
385
|
+
throw new Error(`Version ${version} is not a diff version`);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
syncStatus() {
|
|
389
|
+
return this.status;
|
|
354
390
|
}
|
|
355
|
-
|
|
356
|
-
return this.status
|
|
391
|
+
statusObj() {
|
|
392
|
+
return this.status;
|
|
393
|
+
}
|
|
394
|
+
async recordRemovalUploadAndGC() {
|
|
395
|
+
await this.status.recordRemoteRemovalCompletion();
|
|
396
|
+
this.scheduleSelfGC();
|
|
357
397
|
}
|
|
358
398
|
}
|
|
359
399
|
exports.SyncedObj = SyncedObj;
|
|
@@ -368,5 +408,4 @@ async function isOnDisk(path) {
|
|
|
368
408
|
throw exc;
|
|
369
409
|
}));
|
|
370
410
|
}
|
|
371
|
-
function noop() { }
|
|
372
411
|
Object.freeze(exports);
|