core-3nweb-client-lib 0.25.5 → 0.26.1
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/files.d.ts +23 -20
- package/build/core/asmail/config/common.js +2 -2
- package/build/core/asmail/delivery/index.js +4 -3
- package/build/core/asmail/delivery/msg.js +5 -4
- package/build/core/asmail/delivery/per-recipient-wip.js +2 -2
- package/build/core/asmail/inbox/attachments/fs.js +6 -0
- package/build/core/asmail/inbox/cached-msgs.js +2 -2
- package/build/core/asmail/inbox/inbox-events.js +2 -1
- package/build/core/asmail/inbox/index.js +2 -2
- package/build/core/asmail/inbox/msg-downloader.js +2 -2
- package/build/core/asmail/inbox/msg-indexing.js +3 -3
- package/build/core/asmail/inbox/msg-on-disk.js +2 -2
- package/build/core/asmail/keyring/keyring-storage.js +2 -2
- package/build/core/asmail/sending-params/own-params.js +2 -2
- package/build/core/asmail/sending-params/params-from-others.js +2 -2
- package/build/core/id-manager.js +2 -2
- package/build/core/sign-in.d.ts +5 -4
- package/build/core/sign-in.js +9 -11
- package/build/core/sign-up.d.ts +1 -0
- package/build/core/sign-up.js +7 -3
- 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 +43 -0
- package/build/core/storage/common/obj-info-file.js +119 -3
- package/build/core/storage/index.js +1 -1
- package/build/core/storage/local/obj-files-gc.js +8 -6
- package/build/core/storage/local/obj-files.d.ts +3 -3
- package/build/core/storage/local/obj-files.js +9 -9
- package/build/core/storage/local/obj-status.d.ts +9 -25
- package/build/core/storage/local/obj-status.js +28 -110
- package/build/core/storage/local/storage.d.ts +8 -1
- package/build/core/storage/local/storage.js +10 -2
- package/build/core/storage/synced/downloader.js +6 -5
- package/build/core/storage/synced/obj-files-gc.d.ts +1 -0
- package/build/core/storage/synced/obj-files-gc.js +44 -5
- package/build/core/storage/synced/obj-files.d.ts +13 -20
- package/build/core/storage/synced/obj-files.js +70 -48
- package/build/core/storage/synced/obj-status.d.ts +74 -15
- package/build/core/storage/synced/obj-status.js +291 -107
- package/build/core/storage/synced/remote-events.js +32 -26
- package/build/core/storage/synced/storage.d.ts +11 -1
- package/build/core/storage/synced/storage.js +28 -3
- package/build/core/storage/synced/upsyncer.d.ts +8 -7
- package/build/core/storage/synced/upsyncer.js +211 -163
- package/build/ipc-via-protobuf/asmail-cap.js +17 -34
- package/build/ipc-via-protobuf/connector-clients-side.d.ts +2 -0
- package/build/ipc-via-protobuf/connector-clients-side.js +50 -12
- package/build/ipc-via-protobuf/file.js +26 -18
- package/build/ipc-via-protobuf/fs.js +33 -35
- package/build/ipc-via-protobuf/mailerid.js +3 -2
- package/build/ipc-via-protobuf/protobuf-msg.d.ts +2 -0
- package/build/ipc-via-protobuf/protobuf-msg.js +11 -1
- package/build/ipc-via-protobuf/startup-cap.js +5 -5
- package/build/lib-client/3nstorage/exceptions.d.ts +9 -8
- package/build/lib-client/3nstorage/exceptions.js +18 -9
- package/build/lib-client/3nstorage/service.js +10 -6
- package/build/lib-client/3nstorage/xsp-fs/common.d.ts +18 -4
- package/build/lib-client/3nstorage/xsp-fs/common.js +6 -1
- package/build/lib-client/3nstorage/xsp-fs/file-node.js +3 -3
- package/build/lib-client/3nstorage/xsp-fs/file.js +4 -1
- package/build/lib-client/3nstorage/xsp-fs/folder-node.js +27 -13
- package/build/lib-client/3nstorage/xsp-fs/fs.d.ts +11 -6
- package/build/lib-client/3nstorage/xsp-fs/fs.js +189 -58
- package/build/lib-client/3nstorage/xsp-fs/node-in-fs.d.ts +4 -0
- package/build/lib-client/3nstorage/xsp-fs/node-in-fs.js +51 -24
- package/build/lib-client/3nstorage/xsp-fs/node-persistence.js +2 -2
- package/build/lib-client/3nstorage/xsp-fs/xsp-payload-v1.js +2 -2
- package/build/lib-client/3nstorage/xsp-fs/xsp-payload-v2.js +3 -3
- package/build/lib-client/cryptor/cryptor-in-worker.js +4 -4
- package/build/lib-client/cryptor/cryptor-wasm.js +1 -1
- package/build/lib-client/cryptor/cryptor.wasm +0 -0
- package/build/lib-client/cryptor/in-proc-wasm.js +2 -2
- package/build/lib-client/files.js +2 -0
- package/build/lib-client/fs-collection.js +3 -2
- package/build/lib-client/logging/log-to-file.js +4 -4
- package/build/lib-client/objs-on-disk/file-writing-proc.js +2 -2
- package/build/lib-client/objs-on-disk/obj-folders.js +2 -2
- package/build/lib-client/request-utils.js +2 -2
- package/build/lib-client/server-events.js +4 -3
- package/build/lib-client/ws-utils.js +2 -2
- package/build/lib-common/async-fs-node.js +4 -3
- package/build/lib-common/byte-streaming/wrapping.js +17 -17
- package/build/lib-common/exceptions/file.js +6 -1
- package/build/lib-common/ipc/generic-ipc.js +2 -2
- package/build/lib-common/json-utils.js +2 -1
- package/build/lib-common/objs-on-disk/obj-file.js +4 -3
- package/build/lib-common/objs-on-disk/utils.js +2 -2
- 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/service-api/3nstorage/owner.d.ts +5 -4
- package/build/lib-common/service-api/3nstorage/owner.js +3 -2
- package/build/lib-common/utils-for-observables.d.ts +15 -1
- package/build/lib-common/utils-for-observables.js +68 -17
- package/build/protos/asmail.proto.js +404 -78
- package/build/protos/file.proto.js +370 -44
- package/build/protos/fs.proto.js +404 -78
- package/package.json +4 -4
- package/protos/file.proto +10 -2
- package/protos/fs.proto +2 -2
- package/build/core/storage/synced/upsync-status.d.ts +0 -41
- package/build/core/storage/synced/upsync-status.js +0 -158
|
@@ -16,52 +16,61 @@
|
|
|
16
16
|
this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
17
|
*/
|
|
18
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
-
exports.ObjStatus = void 0;
|
|
20
|
-
const processes_1 = require("../../../lib-common/processes");
|
|
21
|
-
const fs = require("../../../lib-common/async-fs-node");
|
|
19
|
+
exports.readAndCheckStatus = exports.ObjStatus = exports.STATUS_FILE_NAME = void 0;
|
|
22
20
|
const path_1 = require("path");
|
|
23
21
|
const exceptions_1 = require("../../../lib-client/3nstorage/exceptions");
|
|
22
|
+
const json_saving_1 = require("../common/json-saving");
|
|
24
23
|
const obj_info_file_1 = require("../common/obj-info-file");
|
|
25
|
-
const
|
|
24
|
+
const json_utils_1 = require("../../../lib-common/json-utils");
|
|
25
|
+
exports.STATUS_FILE_NAME = 'status';
|
|
26
26
|
class ObjStatus {
|
|
27
|
-
constructor(objFolder, status) {
|
|
27
|
+
constructor(objFolder, status, logError) {
|
|
28
28
|
this.objFolder = objFolder;
|
|
29
29
|
this.status = status;
|
|
30
|
-
this.
|
|
30
|
+
this.logError = logError;
|
|
31
|
+
this.saveProc = new json_saving_1.JSONSavingProc(path_1.join(this.objFolder, exports.STATUS_FILE_NAME), () => this.status);
|
|
31
32
|
Object.freeze(this);
|
|
32
33
|
}
|
|
33
|
-
static async readFrom(objFolder, objId) {
|
|
34
|
+
static async readFrom(objFolder, objId, logError) {
|
|
34
35
|
const status = await readAndCheckStatus(objFolder, objId);
|
|
35
|
-
return new ObjStatus(objFolder, status);
|
|
36
|
+
return new ObjStatus(objFolder, status, logError);
|
|
36
37
|
}
|
|
37
|
-
static async makeNew(objFolder, objId) {
|
|
38
|
+
static async makeNew(objFolder, objId, logError) {
|
|
38
39
|
const status = {
|
|
39
40
|
objId,
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
sync: {
|
|
42
|
+
state: 'unsynced'
|
|
43
|
+
},
|
|
44
|
+
versions: {
|
|
45
|
+
baseToDiff: {},
|
|
46
|
+
diffToBase: {},
|
|
47
|
+
}
|
|
42
48
|
};
|
|
43
|
-
const s = new ObjStatus(objFolder, status);
|
|
44
|
-
await s.
|
|
49
|
+
const s = new ObjStatus(objFolder, status, logError);
|
|
50
|
+
await s.triggerSaveProc();
|
|
45
51
|
return s;
|
|
46
52
|
}
|
|
47
|
-
static async makeForDownloadedVersion(objFolder, objId, version) {
|
|
53
|
+
static async makeForDownloadedVersion(objFolder, objId, version, currentRemote, logError) {
|
|
48
54
|
const status = {
|
|
49
55
|
objId,
|
|
50
|
-
|
|
56
|
+
sync: {
|
|
57
|
+
state: 'synced',
|
|
58
|
+
remote: currentRemote,
|
|
59
|
+
latest: currentRemote,
|
|
60
|
+
},
|
|
51
61
|
versions: {
|
|
52
|
-
current: version
|
|
62
|
+
current: version,
|
|
63
|
+
baseToDiff: {},
|
|
64
|
+
diffToBase: {}
|
|
53
65
|
}
|
|
54
66
|
};
|
|
55
|
-
const s = new ObjStatus(objFolder, status);
|
|
56
|
-
await s.
|
|
67
|
+
const s = new ObjStatus(objFolder, status, logError);
|
|
68
|
+
await s.triggerSaveProc();
|
|
57
69
|
return s;
|
|
58
70
|
}
|
|
59
71
|
static async fileShowsObjNotInSyncedState(objFolder, objId) {
|
|
60
72
|
const status = await readAndCheckStatus(objFolder, objId);
|
|
61
|
-
return (status.
|
|
62
|
-
}
|
|
63
|
-
async saveFile() {
|
|
64
|
-
await fs.writeFile(path_1.join(this.objFolder, STATUS_FILE_NAME), JSON.stringify(this.status), { encoding: 'utf8' });
|
|
73
|
+
return (status.sync.state !== 'synced');
|
|
65
74
|
}
|
|
66
75
|
isArchived() {
|
|
67
76
|
return !!this.status.isArchived;
|
|
@@ -72,58 +81,98 @@ class ObjStatus {
|
|
|
72
81
|
}
|
|
73
82
|
return this.status.versions.current;
|
|
74
83
|
}
|
|
84
|
+
getNonGarbageVersions() {
|
|
85
|
+
const versions = this.status.versions;
|
|
86
|
+
const nonGarbage = obj_info_file_1.nonGarbageVersionsIn(versions);
|
|
87
|
+
if (this.status.syncTasks) {
|
|
88
|
+
const tasks = this.status.syncTasks;
|
|
89
|
+
if (tasks.current) {
|
|
90
|
+
obj_info_file_1.addWithBasesTo(nonGarbage, nonGarbageVersionInTask(tasks.current), versions);
|
|
91
|
+
}
|
|
92
|
+
for (const t of tasks.queued) {
|
|
93
|
+
obj_info_file_1.addWithBasesTo(nonGarbage, nonGarbageVersionInTask(t), versions);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
nonGarbage,
|
|
98
|
+
gcMaxVer: versions.current
|
|
99
|
+
};
|
|
100
|
+
}
|
|
75
101
|
isRemoteVersionGreaterOrEqualTo(newRemoteVersion) {
|
|
76
|
-
return ((typeof this.status.
|
|
77
|
-
(this.status.
|
|
102
|
+
return ((typeof this.status.sync.remote === 'number') ?
|
|
103
|
+
(this.status.sync.remote >= newRemoteVersion) : false);
|
|
78
104
|
}
|
|
79
105
|
isDeletedOnRemote() {
|
|
80
|
-
return !!this.status.deletedOnRemote;
|
|
106
|
+
return !!this.status.sync.deletedOnRemote;
|
|
81
107
|
}
|
|
82
108
|
syncedVersionGreaterOrEqual(version) {
|
|
83
|
-
return ((typeof this.status.
|
|
84
|
-
false : (version <= this.status.
|
|
109
|
+
return ((typeof this.status.sync.latest !== 'number') ?
|
|
110
|
+
false : (version <= this.status.sync.latest));
|
|
85
111
|
}
|
|
86
112
|
async removeCurrentVersion(verObjs) {
|
|
87
113
|
this.status.isArchived = true;
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
114
|
+
const current = obj_info_file_1.rmCurrentVersionIn(this.status.versions);
|
|
115
|
+
if (typeof current === 'number') {
|
|
116
|
+
verObjs.delete(current);
|
|
117
|
+
}
|
|
118
|
+
this.addRemoveCurrentToQueue();
|
|
119
|
+
await this.triggerSaveProc().catch((exc) => {
|
|
120
|
+
if (exc.notFound && this.status.isArchived) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
throw exc;
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
async triggerSaveProc(captureErrors = false, logErr = false) {
|
|
129
|
+
try {
|
|
130
|
+
await this.saveProc.trigger();
|
|
131
|
+
}
|
|
132
|
+
catch (exc) {
|
|
133
|
+
if (captureErrors) {
|
|
134
|
+
if (logErr) {
|
|
135
|
+
await this.logError(exc);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
throw exc;
|
|
140
|
+
}
|
|
92
141
|
}
|
|
93
|
-
await this.saveProc.trigger();
|
|
94
142
|
}
|
|
95
143
|
async setDeletedOnRemote() {
|
|
96
|
-
this.status.deletedOnRemote = true;
|
|
97
|
-
await this.
|
|
144
|
+
this.status.sync.deletedOnRemote = true;
|
|
145
|
+
await this.triggerSaveProc();
|
|
98
146
|
}
|
|
99
147
|
async setRemoteVersion(version) {
|
|
100
|
-
if (this.status.
|
|
148
|
+
if (this.status.sync.remote >= version) {
|
|
101
149
|
return;
|
|
102
150
|
}
|
|
103
|
-
this.status.
|
|
104
|
-
if (this.status.
|
|
105
|
-
if (this.status.versions.current < this.status.
|
|
106
|
-
this.status.
|
|
151
|
+
this.status.sync.remote = version;
|
|
152
|
+
if (this.status.sync.state === 'synced') {
|
|
153
|
+
if (this.status.versions.current < this.status.sync.remote) {
|
|
154
|
+
this.status.sync.state = 'behind';
|
|
107
155
|
}
|
|
108
156
|
}
|
|
109
|
-
else if (this.status.
|
|
110
|
-
this.status.
|
|
157
|
+
else if (this.status.sync.state === 'unsynced') {
|
|
158
|
+
this.status.sync.state = 'conflicting';
|
|
111
159
|
}
|
|
112
|
-
await this.
|
|
160
|
+
await this.triggerSaveProc();
|
|
113
161
|
}
|
|
114
|
-
async
|
|
115
|
-
this.status.
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
162
|
+
async markVersionSynced(version) {
|
|
163
|
+
if (!this.status.sync.latest
|
|
164
|
+
|| (this.status.sync.latest < version)) {
|
|
165
|
+
this.status.sync.latest = version;
|
|
166
|
+
if (this.status.versions.current === version) {
|
|
167
|
+
this.status.sync.state = 'synced';
|
|
168
|
+
}
|
|
169
|
+
await this.triggerSaveProc();
|
|
170
|
+
}
|
|
119
171
|
}
|
|
120
|
-
async setUnsyncedCurrentVersion(version) {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
this.status.versions.current = version;
|
|
125
|
-
this.status.syncState = 'unsynced';
|
|
126
|
-
await this.saveProc.trigger();
|
|
172
|
+
async setUnsyncedCurrentVersion(version, baseVer) {
|
|
173
|
+
obj_info_file_1.setCurrentVersionIn(this.status.versions, version, baseVer);
|
|
174
|
+
this.status.sync.state = 'unsynced';
|
|
175
|
+
await this.triggerSaveProc();
|
|
127
176
|
}
|
|
128
177
|
/**
|
|
129
178
|
* This method ignores remote conflicting versions.
|
|
@@ -133,20 +182,196 @@ class ObjStatus {
|
|
|
133
182
|
if (this.status.versions.current === undefined) {
|
|
134
183
|
return false;
|
|
135
184
|
}
|
|
136
|
-
if (this.status.
|
|
185
|
+
if (this.status.sync.state == 'synced') {
|
|
137
186
|
return true;
|
|
138
187
|
}
|
|
139
|
-
if (this.status.
|
|
188
|
+
if (this.status.sync.latest === undefined) {
|
|
140
189
|
return false;
|
|
141
190
|
}
|
|
142
|
-
return (this.status.
|
|
191
|
+
return (this.status.sync.latest >= version);
|
|
192
|
+
}
|
|
193
|
+
isVersionArchived(version) {
|
|
194
|
+
if (!this.status.versions.archived) {
|
|
195
|
+
return false;
|
|
196
|
+
}
|
|
197
|
+
return this.status.versions.archived.includes(version);
|
|
198
|
+
}
|
|
199
|
+
queueTask(t) {
|
|
200
|
+
if (t.type === 'upload') {
|
|
201
|
+
this.addUploadToQueue(t);
|
|
202
|
+
}
|
|
203
|
+
else if (t.type === 'removal') {
|
|
204
|
+
if (t.currentVersion) {
|
|
205
|
+
throw new Error(`Removal of current task needs other method`);
|
|
206
|
+
}
|
|
207
|
+
else if (t.archivedVersions) {
|
|
208
|
+
this.addRemoveArchivedToQueue(t.archivedVersions);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
else if (t.type === 'archiving') {
|
|
212
|
+
this.addArchivalToQueue(t);
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
throw new Error(`Unsupported upsync task type`);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
addUploadToQueue(u) {
|
|
219
|
+
if (!this.status.syncTasks) {
|
|
220
|
+
this.status.syncTasks = { queued: [u] };
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
const q = this.status.syncTasks.queued;
|
|
224
|
+
const last = lastIn(q);
|
|
225
|
+
if (last) {
|
|
226
|
+
if (last.type === 'upload') {
|
|
227
|
+
if (!this.isVersionArchived(last.version)) {
|
|
228
|
+
if (last.createObj) {
|
|
229
|
+
u.createObj = true;
|
|
230
|
+
}
|
|
231
|
+
q[q.length - 1] = u;
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
q.push(u);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
else if (last.type === 'archiving') {
|
|
238
|
+
q.push(u);
|
|
239
|
+
}
|
|
240
|
+
else if ((last.type === 'removal') && last.archivedVersions) {
|
|
241
|
+
q.push(u);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
q.push(u);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
this.triggerSaveProc(true);
|
|
249
|
+
}
|
|
250
|
+
addRemoveCurrentToQueue() {
|
|
251
|
+
const r = { type: 'removal', currentVersion: true };
|
|
252
|
+
if (this.status.syncTasks) {
|
|
253
|
+
const q = this.status.syncTasks.queued;
|
|
254
|
+
const last = lastIn(q);
|
|
255
|
+
if (last) {
|
|
256
|
+
if (last.type === 'archiving') {
|
|
257
|
+
q.push(r);
|
|
258
|
+
}
|
|
259
|
+
else if (last.type === 'upload') {
|
|
260
|
+
if (this.isVersionArchived(last.version)) {
|
|
261
|
+
q.push(r);
|
|
262
|
+
}
|
|
263
|
+
else if (this.status.sync.latest
|
|
264
|
+
|| this.status.syncTasks.current) {
|
|
265
|
+
q[q.length - 1] = r;
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
q.splice(q.length - 1, 1);
|
|
269
|
+
this.addRemoveCurrentToQueue();
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
else if (this.status.sync.latest
|
|
275
|
+
|| this.status.syncTasks.current) {
|
|
276
|
+
q.push(r);
|
|
277
|
+
}
|
|
278
|
+
else {
|
|
279
|
+
this.status.syncTasks = undefined;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
else {
|
|
283
|
+
if (this.status.sync.latest) {
|
|
284
|
+
this.status.syncTasks = { queued: [r] };
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
addRemoveArchivedToQueue(archVer) {
|
|
289
|
+
const r = { type: 'removal', archivedVersions: archVer };
|
|
290
|
+
if (this.status.syncTasks) {
|
|
291
|
+
this.status.syncTasks.queued.push(r);
|
|
292
|
+
}
|
|
293
|
+
else {
|
|
294
|
+
this.status.syncTasks = { queued: [r] };
|
|
295
|
+
}
|
|
296
|
+
this.triggerSaveProc(true);
|
|
297
|
+
}
|
|
298
|
+
addArchivalToQueue(a) {
|
|
299
|
+
if (!this.status.syncTasks) {
|
|
300
|
+
this.status.syncTasks = { queued: [a] };
|
|
301
|
+
}
|
|
302
|
+
else {
|
|
303
|
+
this.status.syncTasks.queued.push(a);
|
|
304
|
+
}
|
|
305
|
+
this.triggerSaveProc(true);
|
|
306
|
+
}
|
|
307
|
+
async getTaskForProcessing() {
|
|
308
|
+
const syncTasks = this.status.syncTasks;
|
|
309
|
+
if (!syncTasks) {
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
if (syncTasks.current) {
|
|
313
|
+
return syncTasks.current;
|
|
314
|
+
}
|
|
315
|
+
syncTasks.current = syncTasks.queued.shift();
|
|
316
|
+
if (syncTasks.current) {
|
|
317
|
+
await this.triggerSaveProc();
|
|
318
|
+
}
|
|
319
|
+
return syncTasks.current;
|
|
320
|
+
}
|
|
321
|
+
glanceOnNextTask() {
|
|
322
|
+
const syncTasks = this.status.syncTasks;
|
|
323
|
+
if (!syncTasks) {
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
if (syncTasks.current) {
|
|
327
|
+
return syncTasks.current;
|
|
328
|
+
}
|
|
329
|
+
else if (syncTasks.queued.length > 0) {
|
|
330
|
+
return syncTasks.queued[0];
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
async recordInterimStateOfCurrentTask(t) {
|
|
334
|
+
const syncTasks = this.status.syncTasks;
|
|
335
|
+
if (!syncTasks) {
|
|
336
|
+
throw new Error(`This method is called too early.`);
|
|
337
|
+
}
|
|
338
|
+
if (syncTasks.current === t) {
|
|
339
|
+
await this.triggerSaveProc();
|
|
340
|
+
}
|
|
341
|
+
else {
|
|
342
|
+
throw new Error(`Can save interim state of a current task only`);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
async recordTaskCompletion(t) {
|
|
346
|
+
const syncTasks = this.status.syncTasks;
|
|
347
|
+
if (!syncTasks) {
|
|
348
|
+
throw new Error(`This method is called too early.`);
|
|
349
|
+
}
|
|
350
|
+
if (syncTasks.current === t) {
|
|
351
|
+
if (syncTasks.queued.length > 0) {
|
|
352
|
+
syncTasks.current = undefined;
|
|
353
|
+
}
|
|
354
|
+
else {
|
|
355
|
+
this.status.syncTasks = undefined;
|
|
356
|
+
}
|
|
357
|
+
await this.triggerSaveProc();
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
isSyncDone() {
|
|
361
|
+
return !this.status.syncTasks;
|
|
362
|
+
}
|
|
363
|
+
isFileSaved() {
|
|
364
|
+
return this.saveProc.isSaved();
|
|
365
|
+
}
|
|
366
|
+
stat() {
|
|
367
|
+
return json_utils_1.copy(this.status.sync);
|
|
143
368
|
}
|
|
144
369
|
}
|
|
145
370
|
exports.ObjStatus = ObjStatus;
|
|
146
371
|
Object.freeze(ObjStatus.prototype);
|
|
147
372
|
Object.freeze(ObjStatus);
|
|
148
373
|
async function readAndCheckStatus(objFolder, objId) {
|
|
149
|
-
const status = await obj_info_file_1.readJSONInfoFileIn(objFolder, STATUS_FILE_NAME);
|
|
374
|
+
const status = await obj_info_file_1.readJSONInfoFileIn(objFolder, exports.STATUS_FILE_NAME);
|
|
150
375
|
if (!status) {
|
|
151
376
|
throw exceptions_1.makeStorageException({
|
|
152
377
|
message: `Obj status file is not found in obj folder ${objFolder}`
|
|
@@ -158,54 +383,13 @@ async function readAndCheckStatus(objFolder, objId) {
|
|
|
158
383
|
}
|
|
159
384
|
return status;
|
|
160
385
|
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
//
|
|
170
|
-
// if (status.baseToDiff[ver]) { return; }
|
|
171
|
-
// const base = status.diffToBase[ver];
|
|
172
|
-
// if (typeof base !== 'number') { return; }
|
|
173
|
-
// delete status.diffToBase[ver];
|
|
174
|
-
// const diffs = status.baseToDiff[base];
|
|
175
|
-
// if (!diffs) { return; }
|
|
176
|
-
// const diffInd = diffs.indexOf(ver);
|
|
177
|
-
// if (diffInd < 0) { return; }
|
|
178
|
-
// diffs.splice(diffInd, 1);
|
|
179
|
-
// if (diffs.length === 0) {
|
|
180
|
-
// delete status.baseToDiff[base];
|
|
181
|
-
// rmNonArchVersionsIn(status, base);
|
|
182
|
-
// }
|
|
386
|
+
exports.readAndCheckStatus = readAndCheckStatus;
|
|
387
|
+
function lastIn(arr) {
|
|
388
|
+
return ((arr.length > 0) ? arr[arr.length - 1] : undefined);
|
|
389
|
+
}
|
|
390
|
+
function nonGarbageVersionInTask(task) {
|
|
391
|
+
if (task.type === 'upload') {
|
|
392
|
+
return task.version;
|
|
393
|
+
}
|
|
183
394
|
}
|
|
184
|
-
// export function setNewCurrentVersionAfterWriteIn(
|
|
185
|
-
// status: ObjStatusInfo, newVersion: number, baseVer: number|undefined
|
|
186
|
-
// ): void {
|
|
187
|
-
// if (status.isArchived) { return; }
|
|
188
|
-
// if (status.syncState === 'synced') {
|
|
189
|
-
// status.syncState = 'unsynced';
|
|
190
|
-
// }
|
|
191
|
-
// if (baseVer !== undefined) {
|
|
192
|
-
// // base->diff links should be added before removals
|
|
193
|
-
// addBaseToDiffLinkInStatus(status, newVersion, baseVer);
|
|
194
|
-
// }
|
|
195
|
-
// if (status.versions.current) {
|
|
196
|
-
// rmNonArchVersionsIn(status, status.versions.current);
|
|
197
|
-
// }
|
|
198
|
-
// status.versions.current = newVersion;
|
|
199
|
-
// }
|
|
200
|
-
// export function addConflictingRemoteVersionTo(
|
|
201
|
-
// status: ObjStatusInfo, conflictVersion: number
|
|
202
|
-
// ): void {
|
|
203
|
-
// if (!status.versions.conflictingRemote) {
|
|
204
|
-
// status.versions.conflictingRemote = [];
|
|
205
|
-
// }
|
|
206
|
-
// const conflicts = status.versions.conflictingRemote;
|
|
207
|
-
// if (conflicts.find(v => v >= conflictVersion)) { return; }
|
|
208
|
-
// status.syncState = 'conflicting';
|
|
209
|
-
// status.versions.conflictingRemote.push(conflictVersion);
|
|
210
|
-
// }
|
|
211
395
|
Object.freeze(exports);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/*
|
|
3
|
-
Copyright (C) 2019 - 2020 3NSoft Inc.
|
|
3
|
+
Copyright (C) 2019 - 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.RemoteEvents = void 0;
|
|
19
20
|
const rxjs_1 = require("rxjs");
|
|
@@ -37,7 +38,11 @@ class RemoteEvents {
|
|
|
37
38
|
const objRemoval$ = serverEvents.observe(owner_1.objRemoved.EVENT_NAME)
|
|
38
39
|
.pipe(operators_1.filter(objRm => !!objRm.objId), operators_1.mergeMap(objRm => this.remoteRemoval(objRm)));
|
|
39
40
|
this.absorbingRemoteEventsProc = rxjs_1.merge(objChange$, objRemoval$)
|
|
40
|
-
.subscribe(
|
|
41
|
+
.subscribe({
|
|
42
|
+
next: noop,
|
|
43
|
+
error: err => this.logError(err),
|
|
44
|
+
complete: () => { this.absorbingRemoteEventsProc = undefined; }
|
|
45
|
+
});
|
|
41
46
|
}
|
|
42
47
|
async close() {
|
|
43
48
|
if (this.absorbingRemoteEventsProc) {
|
|
@@ -59,19 +64,19 @@ class RemoteEvents {
|
|
|
59
64
|
return;
|
|
60
65
|
}
|
|
61
66
|
await obj.setRemoteVersion(objChange.newVer);
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
await nodeInFS.processRemoteEvent({
|
|
66
|
-
type: 'remote-change',
|
|
67
|
-
newVer: objChange.newVer,
|
|
68
|
-
objId: objChange.objId
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
catch (err) {
|
|
73
|
-
this.logError(err, `Error in processing remote change event`);
|
|
67
|
+
const nodeInFS = this.fsNodes(objChange.objId);
|
|
68
|
+
if (!nodeInFS) {
|
|
69
|
+
return;
|
|
74
70
|
}
|
|
71
|
+
await nodeInFS.processRemoteEvent({
|
|
72
|
+
type: 'remote-change',
|
|
73
|
+
newVer: objChange.newVer,
|
|
74
|
+
objId: objChange.objId
|
|
75
|
+
}).catch(async (exc) => {
|
|
76
|
+
if (!exc.notFound) {
|
|
77
|
+
await this.logError(exc, `Error in processing remote change event`);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
75
80
|
}
|
|
76
81
|
async remoteRemoval(objRm) {
|
|
77
82
|
const obj = await this.files.findObj(objRm.objId);
|
|
@@ -82,21 +87,22 @@ class RemoteEvents {
|
|
|
82
87
|
return;
|
|
83
88
|
}
|
|
84
89
|
await obj.setDeletedOnRemote();
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
await nodeInFS.processRemoteEvent({
|
|
89
|
-
type: 'remote-delete',
|
|
90
|
-
objId: objRm.objId
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
catch (err) {
|
|
95
|
-
this.logError(err, `Error in processing remote change event`);
|
|
90
|
+
const nodeInFS = this.fsNodes(objRm.objId);
|
|
91
|
+
if (!nodeInFS) {
|
|
92
|
+
return;
|
|
96
93
|
}
|
|
94
|
+
await nodeInFS.processRemoteEvent({
|
|
95
|
+
type: 'remote-delete',
|
|
96
|
+
objId: objRm.objId
|
|
97
|
+
}).catch(async (exc) => {
|
|
98
|
+
if (!exc.notFound) {
|
|
99
|
+
await this.logError(exc, `Error in processing remote removal event`);
|
|
100
|
+
}
|
|
101
|
+
});
|
|
97
102
|
}
|
|
98
103
|
}
|
|
99
104
|
exports.RemoteEvents = RemoteEvents;
|
|
100
105
|
Object.freeze(RemoteEvents.prototype);
|
|
101
106
|
Object.freeze(RemoteEvents);
|
|
107
|
+
function noop() { }
|
|
102
108
|
Object.freeze(exports);
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { IGetMailerIdSigner } from '../../../lib-client/user-with-mid-session';
|
|
2
|
-
import { SyncedStorage as ISyncedStorage, NodesContainer, Storage as IStorage, StorageGetter, ObjId } from '../../../lib-client/3nstorage/xsp-fs/common';
|
|
2
|
+
import { SyncedStorage as ISyncedStorage, NodesContainer, Storage as IStorage, StorageGetter, ObjId, NodeEvent } from '../../../lib-client/3nstorage/xsp-fs/common';
|
|
3
3
|
import { ScryptGenParams } from '../../../lib-client/key-derivation';
|
|
4
4
|
import { LogError } from '../../../lib-client/logging/log-to-file';
|
|
5
5
|
import { AsyncSBoxCryptor, Subscribe, ObjSource } from 'xsp-files';
|
|
6
6
|
import { NetClient } from '../../../lib-client/request-utils';
|
|
7
|
+
import { Observable } from 'rxjs';
|
|
8
|
+
declare type FolderEvent = web3n.files.FolderEvent;
|
|
9
|
+
declare type FileEvent = web3n.files.FileEvent;
|
|
10
|
+
declare type Stats = web3n.files.Stats;
|
|
7
11
|
export declare class SyncedStore implements ISyncedStorage {
|
|
8
12
|
private readonly files;
|
|
9
13
|
private readonly remoteStorage;
|
|
@@ -15,12 +19,17 @@ export declare class SyncedStore implements ISyncedStorage {
|
|
|
15
19
|
readonly nodes: NodesContainer;
|
|
16
20
|
private readonly remoteEvents;
|
|
17
21
|
private readonly uploader;
|
|
22
|
+
private readonly events;
|
|
18
23
|
private constructor();
|
|
19
24
|
static makeAndStart(path: string, user: string, getSigner: IGetMailerIdSigner, getStorages: StorageGetter, cryptor: AsyncSBoxCryptor, remoteServiceUrl: () => Promise<string>, makeNet: () => NetClient, logError: LogError): Promise<{
|
|
20
25
|
syncedStore: ISyncedStorage;
|
|
21
26
|
startObjProcs: () => void;
|
|
22
27
|
}>;
|
|
28
|
+
getNodeEvents(): Observable<NodeEvent>;
|
|
29
|
+
broadcastNodeEvent(objId: ObjId, parentObjId: ObjId | undefined, event: FolderEvent | FileEvent): void;
|
|
30
|
+
private broadcastUpSyncEvent;
|
|
23
31
|
storageForLinking(type: web3n.files.FSType, location?: string): IStorage;
|
|
32
|
+
getObjSyncInfo(objId: ObjId): Promise<Stats['sync']>;
|
|
24
33
|
getRootKeyDerivParamsFromServer(): Promise<ScryptGenParams>;
|
|
25
34
|
generateNewObjId(): Promise<string>;
|
|
26
35
|
private objFromDiskOrDownload;
|
|
@@ -31,3 +40,4 @@ export declare class SyncedStore implements ISyncedStorage {
|
|
|
31
40
|
removeObj(objId: string): Promise<void>;
|
|
32
41
|
close(): Promise<void>;
|
|
33
42
|
}
|
|
43
|
+
export {};
|