core-3nweb-client-lib 0.25.6 → 0.27.0
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/README.md +2 -2
- package/build/api-defs/asmail.d.ts +1 -1
- package/build/api-defs/files.d.ts +282 -70
- package/build/core/app-files.js +7 -7
- package/build/core/asmail/config/common.js +4 -4
- 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 +7 -6
- package/build/core/asmail/delivery/msg.js +8 -7
- package/build/core/asmail/delivery/per-recipient-wip.js +3 -3
- package/build/core/asmail/inbox/attachments/fs.js +11 -1
- package/build/core/asmail/inbox/cached-msgs.js +3 -3
- package/build/core/asmail/inbox/inbox-events.js +5 -4
- package/build/core/asmail/inbox/index.js +12 -12
- package/build/core/asmail/inbox/msg-downloader.js +3 -3
- package/build/core/asmail/inbox/msg-indexing.js +4 -4
- package/build/core/asmail/inbox/msg-on-disk.js +7 -7
- 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 +4 -3
- 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 +4 -4
- package/build/core/asmail/sending-params/params-from-others.js +3 -3
- package/build/core/id-manager.js +8 -5
- package/build/core/index.d.ts +2 -1
- package/build/core/index.js +14 -14
- package/build/core/sign-in.d.ts +5 -4
- package/build/core/sign-in.js +12 -14
- package/build/core/sign-up.d.ts +1 -0
- package/build/core/sign-up.js +15 -11
- package/build/core/storage/common/json-saving.d.ts +21 -0
- package/build/core/storage/common/json-saving.js +82 -0
- package/build/core/storage/common/obj-info-file.d.ts +51 -0
- package/build/core/storage/common/obj-info-file.js +153 -5
- 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 +3 -17
- package/build/core/storage/index.js +57 -77
- package/build/core/storage/local/obj-files-gc.d.ts +2 -0
- package/build/core/storage/local/obj-files-gc.js +53 -39
- package/build/core/storage/local/obj-files.d.ts +6 -9
- package/build/core/storage/local/obj-files.js +16 -19
- package/build/core/storage/local/obj-status.d.ts +20 -30
- package/build/core/storage/local/obj-status.js +46 -113
- package/build/core/storage/local/storage.d.ts +15 -5
- package/build/core/storage/local/storage.js +37 -18
- package/build/core/storage/synced/downloader.js +7 -6
- package/build/core/storage/synced/obj-files-gc.d.ts +6 -1
- package/build/core/storage/synced/obj-files-gc.js +106 -13
- package/build/core/storage/synced/obj-files.d.ts +46 -47
- package/build/core/storage/synced/obj-files.js +207 -154
- package/build/core/storage/synced/obj-status.d.ts +103 -42
- package/build/core/storage/synced/obj-status.js +525 -137
- package/build/core/storage/synced/remote-events.d.ts +11 -12
- package/build/core/storage/synced/remote-events.js +80 -57
- package/build/core/storage/synced/storage.d.ts +24 -5
- package/build/core/storage/synced/storage.js +123 -38
- 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 +15 -9
- package/build/core/storage/synced/upsyncer.js +219 -246
- 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 +67 -83
- package/build/ipc-via-protobuf/bytes.js +16 -17
- package/build/ipc-via-protobuf/connector-clients-side.d.ts +3 -0
- package/build/ipc-via-protobuf/connector-clients-side.js +62 -25
- 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 +476 -120
- package/build/ipc-via-protobuf/fs.d.ts +8 -0
- package/build/ipc-via-protobuf/fs.js +592 -159
- 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 +23 -23
- package/build/ipc-via-protobuf/storage-cap.js +12 -12
- package/build/ipc.js +7 -2
- package/build/lib-client/3nstorage/exceptions.d.ts +12 -8
- package/build/lib-client/3nstorage/exceptions.js +31 -10
- package/build/lib-client/3nstorage/service.d.ts +16 -2
- package/build/lib-client/3nstorage/service.js +109 -39
- package/build/lib-client/3nstorage/util/file-based-json.d.ts +2 -1
- package/build/lib-client/3nstorage/util/file-based-json.js +1 -1
- package/build/lib-client/3nstorage/xsp-fs/attrs.js +17 -17
- package/build/lib-client/3nstorage/xsp-fs/common.d.ts +52 -14
- package/build/lib-client/3nstorage/xsp-fs/common.js +31 -16
- package/build/lib-client/3nstorage/xsp-fs/file-node.d.ts +1 -0
- package/build/lib-client/3nstorage/xsp-fs/file-node.js +18 -14
- package/build/lib-client/3nstorage/xsp-fs/file.d.ts +31 -6
- package/build/lib-client/3nstorage/xsp-fs/file.js +74 -23
- package/build/lib-client/3nstorage/xsp-fs/folder-node-serialization.js +4 -4
- package/build/lib-client/3nstorage/xsp-fs/folder-node.d.ts +24 -11
- package/build/lib-client/3nstorage/xsp-fs/folder-node.js +599 -189
- package/build/lib-client/3nstorage/xsp-fs/fs.d.ts +45 -9
- package/build/lib-client/3nstorage/xsp-fs/fs.js +326 -74
- 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 -20
- package/build/lib-client/3nstorage/xsp-fs/node-in-fs.js +239 -106
- package/build/lib-client/3nstorage/xsp-fs/node-persistence.d.ts +1 -1
- package/build/lib-client/3nstorage/xsp-fs/node-persistence.js +18 -19
- package/build/lib-client/3nstorage/xsp-fs/xsp-payload-v1.js +5 -5
- package/build/lib-client/3nstorage/xsp-fs/xsp-payload-v2.js +56 -56
- 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 +19 -17
- 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 +7 -7
- 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 -4
- package/build/lib-client/fs-collection.js +3 -2
- 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 +11 -11
- 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 +5 -5
- package/build/lib-client/objs-on-disk/obj-folders.js +33 -33
- 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 +14 -14
- package/build/lib-client/server-events.d.ts +3 -3
- package/build/lib-client/server-events.js +12 -10
- package/build/lib-client/service-locator.js +10 -10
- package/build/lib-client/user-with-mid-session.js +7 -7
- package/build/lib-client/user-with-pkl-session.js +25 -25
- package/build/lib-client/ws-utils.js +3 -3
- 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 +19 -18
- package/build/lib-common/byte-streaming/pipe.js +1 -1
- package/build/lib-common/byte-streaming/wrapping.js +17 -17
- 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.js +10 -1
- package/build/lib-common/ipc/generic-ipc.js +2 -2
- package/build/lib-common/ipc/ws-ipc.js +2 -2
- package/build/lib-common/json-utils.js +2 -1
- 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 +99 -37
- package/build/lib-common/objs-on-disk/utils.d.ts +1 -0
- package/build/lib-common/objs-on-disk/utils.js +4 -4
- package/build/lib-common/objs-on-disk/v1-obj-file-format.js +14 -14
- package/build/lib-common/processes/deferred.d.ts +6 -0
- package/build/lib-common/processes/deferred.js +30 -0
- package/build/lib-common/processes/labelled-exec-pools.d.ts +33 -0
- package/build/lib-common/processes/labelled-exec-pools.js +141 -0
- package/build/lib-common/processes/pressure.d.ts +7 -0
- package/build/lib-common/processes/pressure.js +56 -0
- package/build/lib-common/processes/sleep.d.ts +1 -0
- package/build/lib-common/processes/sleep.js +26 -0
- package/build/lib-common/{processes.d.ts → processes/synced.d.ts} +0 -40
- package/build/lib-common/{processes.js → processes/synced.js} +187 -204
- package/build/lib-common/processes/timeout.d.ts +1 -0
- package/build/lib-common/processes/timeout.js +51 -0
- package/build/lib-common/random-node.js +7 -7
- package/build/lib-common/service-api/3nstorage/owner.d.ts +100 -39
- package/build/lib-common/service-api/3nstorage/owner.js +85 -42
- 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.d.ts +15 -1
- package/build/lib-common/utils-for-observables.js +70 -19
- 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 +12912 -7127
- package/build/protos/file.proto.js +4848 -2399
- package/build/protos/fs.proto.js +9230 -3445
- package/package.json +8 -7
- package/protos/file.proto +91 -11
- package/protos/fs.proto +107 -8
- package/build/core/storage/synced/upsync-status.d.ts +0 -41
- package/build/core/storage/synced/upsync-status.js +0 -158
|
@@ -17,168 +17,101 @@
|
|
|
17
17
|
*/
|
|
18
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
19
|
exports.ObjStatus = void 0;
|
|
20
|
-
const fs = require("../../../lib-common/async-fs-node");
|
|
21
|
-
const processes_1 = require("../../../lib-common/processes");
|
|
22
20
|
const path_1 = require("path");
|
|
23
21
|
const exceptions_1 = require("../../../lib-client/3nstorage/exceptions");
|
|
24
22
|
const obj_info_file_1 = require("../common/obj-info-file");
|
|
23
|
+
const json_saving_1 = require("../common/json-saving");
|
|
24
|
+
const obj_info_file_2 = require("../common/obj-info-file");
|
|
25
|
+
const assert_1 = require("../../../lib-common/assert");
|
|
25
26
|
const STATUS_FILE_NAME = 'status';
|
|
26
27
|
class ObjStatus {
|
|
27
|
-
constructor(objFolder, status) {
|
|
28
|
+
constructor(objFolder, status, logError) {
|
|
28
29
|
this.objFolder = objFolder;
|
|
29
30
|
this.status = status;
|
|
30
|
-
this.
|
|
31
|
+
this.logError = logError;
|
|
32
|
+
this.saveProc = new json_saving_1.JSONSavingProc((0, path_1.join)(this.objFolder, STATUS_FILE_NAME), () => this.status);
|
|
31
33
|
Object.freeze(this);
|
|
32
34
|
}
|
|
33
|
-
static async readFrom(objFolder, objId) {
|
|
35
|
+
static async readFrom(objFolder, objId, logError) {
|
|
34
36
|
const status = await readAndCheckStatus(objFolder, objId);
|
|
35
|
-
return new ObjStatus(objFolder, status);
|
|
37
|
+
return new ObjStatus(objFolder, status, logError);
|
|
36
38
|
}
|
|
37
|
-
static async makeNew(objFolder, objId) {
|
|
39
|
+
static async makeNew(objFolder, objId, logError) {
|
|
38
40
|
const status = {
|
|
39
41
|
objId,
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
42
|
+
versions: {
|
|
43
|
+
baseToDiff: {},
|
|
44
|
+
diffToBase: {}
|
|
45
|
+
}
|
|
43
46
|
};
|
|
44
|
-
const s = new ObjStatus(objFolder, status);
|
|
45
|
-
await s.
|
|
47
|
+
const s = new ObjStatus(objFolder, status, logError);
|
|
48
|
+
await s.triggerSaveProc();
|
|
46
49
|
return s;
|
|
47
50
|
}
|
|
48
|
-
|
|
49
|
-
|
|
51
|
+
triggerSaveProc(captureErrors = false) {
|
|
52
|
+
let p = this.saveProc.trigger();
|
|
53
|
+
return (captureErrors ? p.catch(this.logError) : p);
|
|
50
54
|
}
|
|
51
55
|
isArchived() {
|
|
52
56
|
return !!this.status.isArchived;
|
|
53
57
|
}
|
|
54
58
|
getCurrentVersionOrThrow() {
|
|
55
|
-
if (typeof this.status.
|
|
59
|
+
if (typeof this.status.versions.current !== 'number') {
|
|
56
60
|
throw new Error(`Object ${this.status.objId} has no current version.`);
|
|
57
61
|
}
|
|
58
|
-
return this.status.
|
|
62
|
+
return this.status.versions.current;
|
|
59
63
|
}
|
|
60
64
|
getNonGarbageVersions() {
|
|
61
65
|
return {
|
|
62
|
-
nonGarbage:
|
|
63
|
-
gcMaxVer: this.status.
|
|
66
|
+
nonGarbage: (0, obj_info_file_2.nonGarbageVersionsIn)(this.status.versions),
|
|
67
|
+
gcMaxVer: this.status.versions.current
|
|
64
68
|
};
|
|
65
69
|
}
|
|
66
70
|
async setNewCurrentVersion(newVersion, baseVer) {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
addBaseToDiffLinkInStatus(this.status, newVersion, baseVer);
|
|
70
|
-
}
|
|
71
|
-
if (typeof this.status.currentVersion === 'number') {
|
|
72
|
-
rmNonArchVersionsIn(this.status, this.status.currentVersion);
|
|
73
|
-
}
|
|
74
|
-
this.status.currentVersion = newVersion;
|
|
75
|
-
await this.saveProc.trigger();
|
|
71
|
+
(0, obj_info_file_2.setCurrentVersionIn)(this.status.versions, newVersion, baseVer);
|
|
72
|
+
await this.triggerSaveProc();
|
|
76
73
|
}
|
|
77
74
|
async removeCurrentVersion(verObjs) {
|
|
78
75
|
this.status.isArchived = true;
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
delete this.status.currentVersion;
|
|
76
|
+
const current = (0, obj_info_file_2.rmCurrentVersionIn)(this.status.versions);
|
|
77
|
+
if (typeof current === 'number') {
|
|
78
|
+
verObjs.delete(current);
|
|
83
79
|
}
|
|
84
|
-
await this.
|
|
80
|
+
await this.triggerSaveProc();
|
|
85
81
|
}
|
|
86
82
|
async removeArchivedVersion(version, verObjs) {
|
|
87
83
|
verObjs.delete(version);
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
await this.
|
|
84
|
+
(0, obj_info_file_2.rmArchVersionFrom)(this.status.versions, version);
|
|
85
|
+
await this.triggerSaveProc();
|
|
86
|
+
}
|
|
87
|
+
async archiveCurrentVersion() {
|
|
88
|
+
const versions = this.status.versions;
|
|
89
|
+
(0, assert_1.assert)(!!versions.current);
|
|
90
|
+
(0, obj_info_file_1.addArchived)(versions, versions.current);
|
|
91
|
+
await this.triggerSaveProc();
|
|
92
|
+
}
|
|
93
|
+
listVersions() {
|
|
94
|
+
const archived = this.status.versions.archived;
|
|
95
|
+
return {
|
|
96
|
+
current: this.status.versions.current,
|
|
97
|
+
archived: (archived ? archived.slice() : [])
|
|
98
|
+
};
|
|
96
99
|
}
|
|
97
100
|
}
|
|
98
101
|
exports.ObjStatus = ObjStatus;
|
|
99
102
|
Object.freeze(ObjStatus.prototype);
|
|
100
103
|
Object.freeze(ObjStatus);
|
|
101
|
-
/**
|
|
102
|
-
* This function adds base->diff link to status. Status object is changed in
|
|
103
|
-
* this call.
|
|
104
|
-
* @param status into which a link between versions should be added
|
|
105
|
-
* @param diffVer
|
|
106
|
-
* @param baseVer
|
|
107
|
-
*/
|
|
108
|
-
function addBaseToDiffLinkInStatus(status, diffVer, baseVer) {
|
|
109
|
-
if (diffVer <= baseVer) {
|
|
110
|
-
throw new Error(`Given diff version ${diffVer} is not greater than base version ${baseVer}`);
|
|
111
|
-
}
|
|
112
|
-
status.diffToBase[diffVer] = baseVer;
|
|
113
|
-
const diffs = status.baseToDiff[baseVer];
|
|
114
|
-
if (diffs) {
|
|
115
|
-
if (diffs.indexOf(diffVer) < 0) {
|
|
116
|
-
diffs.push(diffVer);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
else {
|
|
120
|
-
status.baseToDiff[baseVer] = [diffVer];
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* This function removes given version from status object, if it is neither
|
|
125
|
-
* archived, nor is a base for another version. If given version is itself
|
|
126
|
-
* based on another, this function is recursively applied to base version, as
|
|
127
|
-
* well.
|
|
128
|
-
* @param status in which version(s) should be removed
|
|
129
|
-
* @param ver
|
|
130
|
-
*/
|
|
131
|
-
function rmNonArchVersionsIn(status, ver) {
|
|
132
|
-
if (status.archivedVersions.indexOf(ver) >= 0) {
|
|
133
|
-
return;
|
|
134
|
-
}
|
|
135
|
-
if (status.baseToDiff[ver]) {
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
const base = status.diffToBase[ver];
|
|
139
|
-
if (typeof base !== 'number') {
|
|
140
|
-
return;
|
|
141
|
-
}
|
|
142
|
-
delete status.diffToBase[ver];
|
|
143
|
-
const diffs = status.baseToDiff[base];
|
|
144
|
-
if (!diffs) {
|
|
145
|
-
return;
|
|
146
|
-
}
|
|
147
|
-
const diffInd = diffs.indexOf(ver);
|
|
148
|
-
if (diffInd < 0) {
|
|
149
|
-
return;
|
|
150
|
-
}
|
|
151
|
-
diffs.splice(diffInd, 1);
|
|
152
|
-
if (diffs.length === 0) {
|
|
153
|
-
delete status.baseToDiff[base];
|
|
154
|
-
rmNonArchVersionsIn(status, base);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
104
|
async function readAndCheckStatus(objFolder, objId) {
|
|
158
|
-
const status = await
|
|
105
|
+
const status = await (0, obj_info_file_2.readJSONInfoFileIn)(objFolder, STATUS_FILE_NAME);
|
|
159
106
|
if (!status) {
|
|
160
|
-
throw exceptions_1.makeStorageException({
|
|
107
|
+
throw (0, exceptions_1.makeStorageException)({
|
|
161
108
|
message: `Obj status file is not found in obj folder ${objFolder}`
|
|
162
109
|
});
|
|
163
110
|
}
|
|
164
111
|
// XXX we may do some checks and sanitization here
|
|
165
112
|
if (objId !== status.objId) {
|
|
166
|
-
throw exceptions_1.makeStorageException({ message: `Invalid objId in status file for obj ${objId}, in folder ${objFolder}.\nInvalid content:\n${JSON.stringify(status, null, 2)}` });
|
|
113
|
+
throw (0, exceptions_1.makeStorageException)({ message: `Invalid objId in status file for obj ${objId}, in folder ${objFolder}.\nInvalid content:\n${JSON.stringify(status, null, 2)}` });
|
|
167
114
|
}
|
|
168
115
|
return status;
|
|
169
116
|
}
|
|
170
|
-
function nonGarbageVersions(status) {
|
|
171
|
-
const nonGarbage = new Set();
|
|
172
|
-
addWithBasesTo(nonGarbage, status.currentVersion, status);
|
|
173
|
-
for (const archVer of status.archivedVersions) {
|
|
174
|
-
addWithBasesTo(nonGarbage, archVer, status);
|
|
175
|
-
}
|
|
176
|
-
return nonGarbage;
|
|
177
|
-
}
|
|
178
|
-
function addWithBasesTo(nonGarbage, ver, status) {
|
|
179
|
-
while (typeof ver === 'number') {
|
|
180
|
-
nonGarbage.add(ver);
|
|
181
|
-
ver = status.diffToBase[ver];
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
117
|
Object.freeze(exports);
|
|
@@ -1,21 +1,31 @@
|
|
|
1
|
-
import { Storage, NodesContainer, StorageGetter, ObjId } from '../../../lib-client/3nstorage/xsp-fs/common';
|
|
1
|
+
import { Storage, NodesContainer, StorageGetter, ObjId, NodeEvent, LocalObjStatus } from '../../../lib-client/3nstorage/xsp-fs/common';
|
|
2
2
|
import { LogError } from '../../../lib-client/logging/log-to-file';
|
|
3
3
|
import { AsyncSBoxCryptor, Subscribe, ObjSource } from 'xsp-files';
|
|
4
|
+
import { Observable } from 'rxjs';
|
|
5
|
+
declare type FolderEvent = web3n.files.FolderEvent;
|
|
6
|
+
declare type FileEvent = web3n.files.FileEvent;
|
|
7
|
+
declare type FSType = web3n.files.FSType;
|
|
4
8
|
export declare class LocalStorage implements Storage {
|
|
5
9
|
private readonly files;
|
|
6
10
|
private readonly getStorages;
|
|
7
11
|
readonly cryptor: AsyncSBoxCryptor;
|
|
8
12
|
private readonly logError;
|
|
9
|
-
readonly type
|
|
13
|
+
readonly type = "local";
|
|
10
14
|
readonly versioned = true;
|
|
11
15
|
readonly nodes: NodesContainer;
|
|
16
|
+
readonly connect: undefined;
|
|
17
|
+
private readonly events;
|
|
12
18
|
private constructor();
|
|
13
19
|
static makeAndStart(path: string, getStorages: StorageGetter, cryptor: AsyncSBoxCryptor, logError: LogError): Promise<Storage>;
|
|
14
|
-
|
|
20
|
+
getNodeEvents(): Observable<NodeEvent>;
|
|
21
|
+
broadcastNodeEvent(objId: ObjId, parentObjId: ObjId | undefined, childObjId: ObjId | undefined, event: FolderEvent | FileEvent): void;
|
|
22
|
+
storageForLinking(type: FSType, location?: string): Storage;
|
|
23
|
+
private getObjOrThrow;
|
|
24
|
+
status(objId: ObjId): Promise<LocalObjStatus>;
|
|
15
25
|
generateNewObjId(): Promise<string>;
|
|
16
|
-
|
|
17
|
-
getObj(objId: ObjId): Promise<ObjSource>;
|
|
26
|
+
getObjSrc(objId: ObjId, version?: number): Promise<ObjSource>;
|
|
18
27
|
saveObj(objId: string, version: number, encSub: Subscribe): Promise<void>;
|
|
19
28
|
removeObj(objId: string): Promise<void>;
|
|
20
29
|
close(): Promise<void>;
|
|
21
30
|
}
|
|
31
|
+
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/*
|
|
3
|
-
Copyright (C) 2016 - 2020 3NSoft Inc.
|
|
3
|
+
Copyright (C) 2016 - 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
|
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
See the GNU General Public License for more details.
|
|
14
14
|
|
|
15
15
|
You should have received a copy of the GNU General Public License along with
|
|
16
|
-
this program. If not, see <http://www.gnu.org/licenses/>.
|
|
16
|
+
this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
*/
|
|
17
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
19
|
exports.LocalStorage = void 0;
|
|
19
20
|
const common_1 = require("../../../lib-client/3nstorage/xsp-fs/common");
|
|
@@ -22,6 +23,7 @@ const random_node_1 = require("../../../lib-common/random-node");
|
|
|
22
23
|
const ecma_nacl_1 = require("ecma-nacl");
|
|
23
24
|
const buffer_utils_1 = require("../../../lib-common/buffer-utils");
|
|
24
25
|
const obj_files_1 = require("./obj-files");
|
|
26
|
+
const utils_for_observables_1 = require("../../../lib-common/utils-for-observables");
|
|
25
27
|
class LocalStorage {
|
|
26
28
|
constructor(files, getStorages, cryptor, logError) {
|
|
27
29
|
this.files = files;
|
|
@@ -31,12 +33,20 @@ class LocalStorage {
|
|
|
31
33
|
this.type = 'local';
|
|
32
34
|
this.versioned = true;
|
|
33
35
|
this.nodes = new common_1.NodesContainer();
|
|
36
|
+
this.connect = undefined;
|
|
37
|
+
this.events = new utils_for_observables_1.Broadcast();
|
|
34
38
|
Object.seal(this);
|
|
35
39
|
}
|
|
36
40
|
static async makeAndStart(path, getStorages, cryptor, logError) {
|
|
37
41
|
const files = await obj_files_1.ObjFiles.makeFor(path, logError);
|
|
38
42
|
const s = new LocalStorage(files, getStorages, cryptor, logError);
|
|
39
|
-
return common_1.wrapStorageImplementation(s);
|
|
43
|
+
return (0, common_1.wrapStorageImplementation)(s);
|
|
44
|
+
}
|
|
45
|
+
getNodeEvents() {
|
|
46
|
+
return this.events.event$;
|
|
47
|
+
}
|
|
48
|
+
broadcastNodeEvent(objId, parentObjId, childObjId, event) {
|
|
49
|
+
this.events.next({ objId, parentObjId, childObjId, event });
|
|
40
50
|
}
|
|
41
51
|
storageForLinking(type, location) {
|
|
42
52
|
if ((type === 'local') || (type === 'synced')) {
|
|
@@ -49,8 +59,22 @@ class LocalStorage {
|
|
|
49
59
|
throw new Error(`Getting ${type} storage is not implemented in local storage.`);
|
|
50
60
|
}
|
|
51
61
|
}
|
|
62
|
+
async getObjOrThrow(objId, allowArchived = false) {
|
|
63
|
+
const obj = await this.files.findObj(objId);
|
|
64
|
+
if (!obj
|
|
65
|
+
|| (!allowArchived && obj.statusObj().isArchived())) {
|
|
66
|
+
throw (0, exceptions_1.makeObjNotFoundExc)(objId);
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
return obj;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
async status(objId) {
|
|
73
|
+
const obj = await this.getObjOrThrow(objId);
|
|
74
|
+
return obj.localStatus();
|
|
75
|
+
}
|
|
52
76
|
async generateNewObjId() {
|
|
53
|
-
const nonce = await random_node_1.bytes(ecma_nacl_1.secret_box.NONCE_LENGTH);
|
|
77
|
+
const nonce = await (0, random_node_1.bytes)(ecma_nacl_1.secret_box.NONCE_LENGTH);
|
|
54
78
|
const id = buffer_utils_1.base64urlSafe.pack(nonce);
|
|
55
79
|
if (this.nodes.reserveId(id)) {
|
|
56
80
|
return id;
|
|
@@ -59,40 +83,35 @@ class LocalStorage {
|
|
|
59
83
|
return this.generateNewObjId();
|
|
60
84
|
}
|
|
61
85
|
}
|
|
62
|
-
async
|
|
63
|
-
const obj = await this.
|
|
64
|
-
if (!
|
|
65
|
-
|
|
86
|
+
async getObjSrc(objId, version) {
|
|
87
|
+
const obj = await this.getObjOrThrow(objId);
|
|
88
|
+
if (!version) {
|
|
89
|
+
version = obj.statusObj().getCurrentVersionOrThrow();
|
|
66
90
|
}
|
|
67
|
-
return obj;
|
|
68
|
-
}
|
|
69
|
-
async getObj(objId) {
|
|
70
|
-
const obj = await this.getObjNonArchOrThrow(objId);
|
|
71
|
-
const currentVer = obj.getCurrentVersionOrThrow();
|
|
72
|
-
return obj.getObjSrc(currentVer);
|
|
91
|
+
return obj.getObjSrc(version);
|
|
73
92
|
}
|
|
74
93
|
async saveObj(objId, version, encSub) {
|
|
75
94
|
const obj = await this.files.findObj(objId);
|
|
76
95
|
if (version === 1) {
|
|
77
96
|
if (obj) {
|
|
78
|
-
throw exceptions_1.makeObjExistsExc(objId);
|
|
97
|
+
throw (0, exceptions_1.makeObjExistsExc)(objId);
|
|
79
98
|
}
|
|
80
99
|
await this.files.saveFirstVersion(objId, encSub);
|
|
81
100
|
}
|
|
82
101
|
else {
|
|
83
102
|
if (!obj) {
|
|
84
|
-
throw exceptions_1.makeObjNotFoundExc(objId);
|
|
103
|
+
throw (0, exceptions_1.makeObjNotFoundExc)(objId);
|
|
85
104
|
}
|
|
86
105
|
await obj.saveNewVersion(version, encSub);
|
|
87
106
|
}
|
|
88
107
|
}
|
|
89
108
|
async removeObj(objId) {
|
|
90
|
-
const obj = await this.
|
|
109
|
+
const obj = await this.getObjOrThrow(objId);
|
|
91
110
|
await obj.removeCurrentVersion();
|
|
92
111
|
}
|
|
93
112
|
async close() {
|
|
94
113
|
try {
|
|
95
|
-
|
|
114
|
+
this.events.done();
|
|
96
115
|
}
|
|
97
116
|
catch (err) {
|
|
98
117
|
await this.logError(err);
|
|
@@ -13,10 +13,11 @@
|
|
|
13
13
|
See the GNU General Public License for more details.
|
|
14
14
|
|
|
15
15
|
You should have received a copy of the GNU General Public License along with
|
|
16
|
-
this program. If not, see <http://www.gnu.org/licenses/>.
|
|
16
|
+
this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
*/
|
|
17
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
19
|
exports.Downloader = void 0;
|
|
19
|
-
const
|
|
20
|
+
const synced_1 = require("../../../lib-common/processes/synced");
|
|
20
21
|
const buffer_utils_1 = require("../../../lib-common/buffer-utils");
|
|
21
22
|
const MAX_GETTING_CHUNK = 512 * 1024;
|
|
22
23
|
const DOWNLOAD_START_CHUNK = 128 * 1024;
|
|
@@ -28,7 +29,7 @@ class Downloader {
|
|
|
28
29
|
* When it comes to the download start, if chain exists, it means that
|
|
29
30
|
* process has already started.
|
|
30
31
|
*/
|
|
31
|
-
this.downloadProcs = new
|
|
32
|
+
this.downloadProcs = new synced_1.NamedProcs();
|
|
32
33
|
Object.seal(this);
|
|
33
34
|
}
|
|
34
35
|
async sync(objId, version, action) {
|
|
@@ -63,12 +64,12 @@ class Downloader {
|
|
|
63
64
|
chunks.push(chunk);
|
|
64
65
|
ofs += chunk.length;
|
|
65
66
|
}
|
|
66
|
-
return buffer_utils_1.joinByteArrs(chunks);
|
|
67
|
+
return (0, buffer_utils_1.joinByteArrs)(chunks);
|
|
67
68
|
}
|
|
68
69
|
});
|
|
69
70
|
}
|
|
70
|
-
getCurrentObjVersion(objId) {
|
|
71
|
-
return this.sync(objId, -1, async () => {
|
|
71
|
+
async getCurrentObjVersion(objId) {
|
|
72
|
+
return await this.sync(objId, -1, async () => {
|
|
72
73
|
const { header, segsTotalLen, version, segsChunk } = await this.remoteStorage.getCurrentObj(objId, DOWNLOAD_START_CHUNK);
|
|
73
74
|
const layout = {
|
|
74
75
|
sections: [{ src: 'new', ofs: 0, len: segsTotalLen }]
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { SynchronizerOnObjId, SyncedObj } from './obj-files';
|
|
2
|
+
import { StorageOwner as RemoteStorage } from '../../../lib-client/3nstorage/service';
|
|
2
3
|
export declare class GC {
|
|
3
4
|
private readonly sync;
|
|
4
5
|
private readonly rmObjFromCache;
|
|
5
6
|
private readonly rmObjFolder;
|
|
7
|
+
private readonly remote;
|
|
6
8
|
private isStopped;
|
|
7
9
|
/**
|
|
8
10
|
* All gc steps are done in this process.
|
|
@@ -18,8 +20,11 @@ export declare class GC {
|
|
|
18
20
|
* with wip set.
|
|
19
21
|
*/
|
|
20
22
|
private scheduled;
|
|
21
|
-
constructor(sync: SynchronizerOnObjId, rmObjFromCache: (obj: SyncedObj) => void, rmObjFolder: (objId: string) => Promise<void
|
|
23
|
+
constructor(sync: SynchronizerOnObjId, rmObjFromCache: (obj: SyncedObj) => void, rmObjFolder: (objId: string) => Promise<void>, remote: RemoteStorage);
|
|
22
24
|
scheduleCollection: (obj: SyncedObj) => void;
|
|
23
25
|
stop(): Promise<void>;
|
|
24
26
|
private objCollecting;
|
|
27
|
+
private collectIn;
|
|
28
|
+
private upsyncObjRemovalWhenNeeded;
|
|
29
|
+
private checkAndRemoveWholeObjFolder;
|
|
25
30
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/*
|
|
3
|
-
Copyright (C) 2020 3NSoft Inc.
|
|
3
|
+
Copyright (C) 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
|
|
@@ -13,20 +13,27 @@
|
|
|
13
13
|
See the GNU General Public License for more details.
|
|
14
14
|
|
|
15
15
|
You should have received a copy of the GNU General Public License along with
|
|
16
|
-
this program. If not, see <http://www.gnu.org/licenses/>.
|
|
16
|
+
this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
*/
|
|
17
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
19
|
exports.GC = void 0;
|
|
19
|
-
const
|
|
20
|
+
const obj_files_1 = require("./obj-files");
|
|
21
|
+
const synced_1 = require("../../../lib-common/processes/synced");
|
|
22
|
+
const fs = require("../../../lib-common/async-fs-node");
|
|
23
|
+
const path_1 = require("path");
|
|
24
|
+
const utils_1 = require("../common/utils");
|
|
25
|
+
const upload_header_file_1 = require("./upload-header-file");
|
|
20
26
|
class GC {
|
|
21
|
-
constructor(sync, rmObjFromCache, rmObjFolder) {
|
|
27
|
+
constructor(sync, rmObjFromCache, rmObjFolder, remote) {
|
|
22
28
|
this.sync = sync;
|
|
23
29
|
this.rmObjFromCache = rmObjFromCache;
|
|
24
30
|
this.rmObjFolder = rmObjFolder;
|
|
31
|
+
this.remote = remote;
|
|
25
32
|
this.isStopped = false;
|
|
26
33
|
/**
|
|
27
34
|
* All gc steps are done in this process.
|
|
28
35
|
*/
|
|
29
|
-
this.gcProc = new
|
|
36
|
+
this.gcProc = new synced_1.SingleProc();
|
|
30
37
|
/**
|
|
31
38
|
* wip are objects that are currently processed. When wip set is empty,
|
|
32
39
|
* it gets swapped with non-empty scheduled set.
|
|
@@ -51,11 +58,11 @@ class GC {
|
|
|
51
58
|
if (this.wip.size === 0) {
|
|
52
59
|
[this.wip, this.scheduled] = [this.scheduled, this.wip];
|
|
53
60
|
}
|
|
54
|
-
const obj = getAndRemoveOneFrom(this.wip);
|
|
61
|
+
const obj = (0, utils_1.getAndRemoveOneFrom)(this.wip);
|
|
55
62
|
if (!obj) {
|
|
56
63
|
return;
|
|
57
64
|
}
|
|
58
|
-
|
|
65
|
+
await this.sync(obj.objId, () => this.collectIn(obj).catch(utils_1.noop));
|
|
59
66
|
return this.objCollecting();
|
|
60
67
|
};
|
|
61
68
|
Object.seal(this);
|
|
@@ -63,17 +70,103 @@ class GC {
|
|
|
63
70
|
async stop() {
|
|
64
71
|
this.isStopped = true;
|
|
65
72
|
}
|
|
73
|
+
async collectIn(obj) {
|
|
74
|
+
if (obj.statusObj().isArchived()) {
|
|
75
|
+
await this.upsyncObjRemovalWhenNeeded(obj);
|
|
76
|
+
}
|
|
77
|
+
const nonGarbage = obj.statusObj().getNonGarbageVersions();
|
|
78
|
+
if (!(await this.checkAndRemoveWholeObjFolder(obj, nonGarbage))) {
|
|
79
|
+
await removeGarbageFiles(obj, nonGarbage);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
async upsyncObjRemovalWhenNeeded(obj) {
|
|
83
|
+
if (!needsUpsyncOfRemoval(obj)) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
try {
|
|
87
|
+
await this.remote.deleteObj(obj.objId);
|
|
88
|
+
}
|
|
89
|
+
catch (exc) {
|
|
90
|
+
// XXX will need to schedule other attempt to delete on remote
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
await obj.statusObj().recordSyncOfObjRemoval();
|
|
94
|
+
}
|
|
95
|
+
async checkAndRemoveWholeObjFolder(obj, { local, remote }) {
|
|
96
|
+
if (obj.objId
|
|
97
|
+
&& obj.statusObj().isArchived()
|
|
98
|
+
&& !needsUpsyncOfRemoval(obj)
|
|
99
|
+
&& (!local || (local.nonGarbage.size === 0))
|
|
100
|
+
&& (remote.nonGarbage.size === 0)) {
|
|
101
|
+
this.rmObjFromCache(obj);
|
|
102
|
+
await this.rmObjFolder(obj.objId);
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
66
109
|
}
|
|
67
110
|
exports.GC = GC;
|
|
68
111
|
Object.freeze(GC.prototype);
|
|
69
112
|
Object.freeze(GC);
|
|
70
|
-
function
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
|
|
113
|
+
function needsUpsyncOfRemoval(obj) {
|
|
114
|
+
const s = obj.statusObj();
|
|
115
|
+
return !(s.neverUploaded() || (s.syncStatus().state === 'synced'));
|
|
116
|
+
}
|
|
117
|
+
function canRemove(f, { local, remote, uploadVersion }) {
|
|
118
|
+
if (f.endsWith(obj_files_1.UNSYNCED_FILE_NAME_EXT)) {
|
|
119
|
+
const verStr = f.slice(0, f.length - 1 - obj_files_1.UNSYNCED_FILE_NAME_EXT.length);
|
|
120
|
+
return (local ? canGC(verStr, local) : true);
|
|
121
|
+
}
|
|
122
|
+
else if (f.endsWith(obj_files_1.REMOTE_FILE_NAME_EXT)) {
|
|
123
|
+
const verStr = f.slice(0, f.length - 1 - obj_files_1.REMOTE_FILE_NAME_EXT.length);
|
|
124
|
+
return canGC(verStr, remote);
|
|
125
|
+
}
|
|
126
|
+
else if (!!uploadVersion
|
|
127
|
+
&& f.endsWith(upload_header_file_1.UPLOAD_HEADER_FILE_NAME_EXT)) {
|
|
128
|
+
const verStr = f.slice(0, f.length - 1 - upload_header_file_1.UPLOAD_HEADER_FILE_NAME_EXT.length);
|
|
129
|
+
return canGCUploadHeader(verStr, uploadVersion);
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
function canGC(verStr, nonGC) {
|
|
136
|
+
const ver = parseInt(verStr);
|
|
137
|
+
if (isNaN(ver)) {
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
140
|
+
else if (!nonGC.nonGarbage.has(ver)
|
|
141
|
+
&& (!nonGC.gcMaxVer || (ver < nonGC.gcMaxVer))) {
|
|
142
|
+
return true;
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
function canGCUploadHeader(verStr, uploadVersion) {
|
|
149
|
+
const ver = parseInt(verStr);
|
|
150
|
+
if (isNaN(ver)) {
|
|
151
|
+
return true;
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
return (ver === uploadVersion);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
async function removeGarbageFiles(obj, nonGarbage) {
|
|
158
|
+
const lst = await fs.readdir(obj.objFolder).catch(utils_1.noop);
|
|
159
|
+
if (!lst) {
|
|
74
160
|
return;
|
|
75
161
|
}
|
|
76
|
-
|
|
77
|
-
|
|
162
|
+
const rmProcs = [];
|
|
163
|
+
for (const f of lst) {
|
|
164
|
+
if (canRemove(f, nonGarbage)) {
|
|
165
|
+
rmProcs.push(fs.unlink((0, path_1.join)(obj.objFolder, f)).catch(utils_1.noop));
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
if (rmProcs.length > 0) {
|
|
169
|
+
await Promise.all(rmProcs);
|
|
170
|
+
}
|
|
78
171
|
}
|
|
79
172
|
Object.freeze(exports);
|