core-3nweb-client-lib 0.27.0 → 0.27.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/api-defs/files.d.ts +56 -26
- package/build/core/asmail/config/index.d.ts +2 -2
- package/build/core/asmail/config/index.js +2 -2
- package/build/core/asmail/config/invitations-anon.d.ts +10 -24
- package/build/core/asmail/config/invitations-anon.js +43 -31
- package/build/core/asmail/config/published-intro-key.d.ts +11 -22
- package/build/core/asmail/config/published-intro-key.js +47 -38
- package/build/core/asmail/inbox/attachments/fs.d.ts +2 -1
- package/build/core/asmail/inbox/attachments/fs.js +4 -3
- package/build/core/asmail/inbox/index.js +2 -2
- package/build/core/asmail/index.d.ts +1 -1
- package/build/core/asmail/index.js +2 -2
- package/build/core/asmail/keyring/correspondent-keys.d.ts +2 -2
- package/build/core/asmail/keyring/correspondent-keys.js +1 -1
- package/build/core/asmail/keyring/index.d.ts +9 -29
- package/build/core/asmail/keyring/index.js +82 -69
- package/build/core/id-manager/index.d.ts +43 -0
- package/build/core/{id-manager.js → id-manager/index.js} +33 -114
- package/build/core/id-manager/key-storage.d.ts +21 -0
- package/build/core/id-manager/key-storage.js +96 -0
- package/build/core/index.js +22 -25
- package/build/core/sign-in.d.ts +1 -2
- package/build/core/sign-in.js +5 -14
- package/build/core/sign-up.d.ts +2 -0
- package/build/core/sign-up.js +2 -1
- package/build/core/storage/index.d.ts +4 -2
- package/build/core/storage/index.js +36 -57
- package/build/core/storage/local/storage.d.ts +1 -1
- package/build/core/storage/synced/obj-files-gc.d.ts +1 -4
- package/build/core/storage/synced/obj-files-gc.js +1 -18
- package/build/core/storage/synced/obj-files.d.ts +11 -1
- package/build/core/storage/synced/obj-files.js +59 -34
- package/build/core/storage/synced/obj-status.d.ts +19 -7
- package/build/core/storage/synced/obj-status.js +158 -83
- package/build/core/storage/synced/storage.d.ts +7 -2
- package/build/core/storage/synced/storage.js +38 -15
- package/build/core/storage/synced/upsyncer.d.ts +4 -4
- package/build/core/storage/synced/upsyncer.js +14 -9
- package/build/ipc-via-protobuf/file.d.ts +7 -0
- package/build/ipc-via-protobuf/file.js +60 -27
- package/build/ipc-via-protobuf/fs.js +55 -38
- package/build/lib-client/3nstorage/exceptions.d.ts +13 -1
- package/build/lib-client/3nstorage/exceptions.js +9 -3
- package/build/lib-client/3nstorage/service.d.ts +6 -2
- package/build/lib-client/3nstorage/service.js +33 -17
- package/build/lib-client/3nstorage/util/file-based-json.js +2 -1
- package/build/lib-client/3nstorage/util/for-arrays.d.ts +1 -0
- package/build/lib-client/3nstorage/util/for-arrays.js +32 -0
- package/build/lib-client/3nstorage/xsp-fs/common.d.ts +5 -4
- package/build/lib-client/3nstorage/xsp-fs/common.js +1 -0
- package/build/lib-client/3nstorage/xsp-fs/file-node.d.ts +5 -10
- package/build/lib-client/3nstorage/xsp-fs/file-node.js +43 -45
- package/build/lib-client/3nstorage/xsp-fs/file.d.ts +7 -6
- package/build/lib-client/3nstorage/xsp-fs/file.js +14 -20
- package/build/lib-client/3nstorage/xsp-fs/folder-node.d.ts +16 -5
- package/build/lib-client/3nstorage/xsp-fs/folder-node.js +238 -68
- package/build/lib-client/3nstorage/xsp-fs/fs.d.ts +18 -17
- package/build/lib-client/3nstorage/xsp-fs/fs.js +32 -37
- package/build/lib-client/3nstorage/xsp-fs/node-in-fs.d.ts +15 -11
- package/build/lib-client/3nstorage/xsp-fs/node-in-fs.js +72 -22
- package/build/lib-client/3nstorage/xsp-fs/xsp-payload-v1.js +1 -1
- package/build/lib-client/local-files/device-fs.js +11 -11
- package/build/lib-client/objs-on-disk/obj-on-disk.d.ts +5 -2
- package/build/lib-client/objs-on-disk/obj-on-disk.js +16 -1
- package/build/lib-client/user-with-mid-session.d.ts +2 -1
- package/build/lib-client/user-with-mid-session.js +7 -1
- package/build/lib-common/async-fs-node.js +8 -8
- package/build/lib-common/exceptions/file.d.ts +4 -2
- package/build/lib-common/exceptions/file.js +24 -58
- package/build/lib-common/ipc/generic-ipc.js +5 -4
- package/build/lib-common/objs-on-disk/file-layout.js +1 -1
- package/build/lib-common/objs-on-disk/utils.js +1 -1
- package/build/lib-common/service-api/3nstorage/owner.d.ts +8 -9
- package/build/lib-common/service-api/3nstorage/owner.js +2 -1
- package/build/protos/asmail.proto.js +5943 -4348
- package/build/protos/file.proto.js +874 -0
- package/build/protos/fs.proto.js +7014 -5419
- package/package.json +3 -2
- package/protos/file.proto +23 -7
- package/protos/fs.proto +27 -13
- package/build/core/id-manager.d.ts +0 -46
|
@@ -18,11 +18,11 @@ export interface ObjStatusInfo {
|
|
|
18
18
|
local?: LocalVersions;
|
|
19
19
|
synced?: SyncMarker;
|
|
20
20
|
remote: VersionsOnServer;
|
|
21
|
+
upload?: UploadInfo;
|
|
21
22
|
}
|
|
22
23
|
export interface LocalVersions extends VersionsInfo {
|
|
23
24
|
isArchived?: boolean;
|
|
24
25
|
archived?: undefined;
|
|
25
|
-
upload?: UploadInfo;
|
|
26
26
|
}
|
|
27
27
|
export interface SyncMarker {
|
|
28
28
|
version?: number;
|
|
@@ -32,12 +32,19 @@ export interface SyncMarker {
|
|
|
32
32
|
export interface VersionsOnServer extends VersionsInfo {
|
|
33
33
|
isArchived?: boolean;
|
|
34
34
|
}
|
|
35
|
-
export
|
|
35
|
+
export declare type UploadInfo = NewVersionUpload | RemovalUpload;
|
|
36
|
+
export interface NewVersionUpload {
|
|
37
|
+
type: 'new-version';
|
|
36
38
|
localVersion: number;
|
|
37
39
|
uploadVersion: number;
|
|
38
40
|
baseVersion?: number;
|
|
39
41
|
needUpload?: WholeVerOrderedUpload | DiffVerOrderedUpload;
|
|
40
42
|
}
|
|
43
|
+
export interface RemovalUpload {
|
|
44
|
+
type: 'removal';
|
|
45
|
+
isPostponed: boolean;
|
|
46
|
+
localVersion?: number;
|
|
47
|
+
}
|
|
41
48
|
export interface WholeVerOrderedUpload {
|
|
42
49
|
type: 'ordered-whole';
|
|
43
50
|
createObj?: boolean;
|
|
@@ -74,20 +81,24 @@ export declare class ObjStatus implements SyncedObjStatus, UploadStatusRecorder
|
|
|
74
81
|
static makeNew(objFolder: string, objId: ObjId, logError: LogError): Promise<ObjStatus>;
|
|
75
82
|
static makeForDownloadedVersion(objFolder: string, objId: ObjId, version: number, currentRemote: number, logError: LogError): Promise<ObjStatus>;
|
|
76
83
|
static fileShowsObjNotInSyncedState(objFolder: string, objId: ObjId): Promise<boolean>;
|
|
84
|
+
static fileShowsObjNeedsRemovalOnRemote(objFolder: string, objId: ObjId): Promise<boolean>;
|
|
85
|
+
needsRemovalOnRemote(): boolean;
|
|
86
|
+
clearPostponeFlagInRemovalOnRemote(): Promise<boolean>;
|
|
77
87
|
private updateStateIndicator;
|
|
78
88
|
isArchived(): boolean;
|
|
79
89
|
getCurrentLocalOrSynced(): number;
|
|
80
90
|
getNonGarbageVersions(): NonGarbage;
|
|
81
91
|
removeCurrentVersion(): Promise<void>;
|
|
82
92
|
private triggerSaveProc;
|
|
83
|
-
recordUploadStart(info:
|
|
84
|
-
recordUploadInterimState(info:
|
|
85
|
-
recordUploadCancellation(info:
|
|
93
|
+
recordUploadStart(info: NewVersionUpload): Promise<void>;
|
|
94
|
+
recordUploadInterimState(info: NewVersionUpload): Promise<void>;
|
|
95
|
+
recordUploadCancellation(info: NewVersionUpload): Promise<void>;
|
|
96
|
+
recordUploadCompletion(localVersion: number, uploadVersion: number): Promise<void>;
|
|
86
97
|
recordArchVersionRemoval(version: number): Promise<void>;
|
|
87
98
|
recordVersionArchival(version: number): Promise<void>;
|
|
88
99
|
recordRemoteRemoval(): Promise<void>;
|
|
100
|
+
recordRemoteRemovalCompletion(): Promise<void>;
|
|
89
101
|
recordRemoteChange(version: number): Promise<void>;
|
|
90
|
-
recordSyncOfObjRemoval(): Promise<void>;
|
|
91
102
|
recordStatusFromServer({ archived, current }: RemoteObjStatus): Promise<void>;
|
|
92
103
|
/**
|
|
93
104
|
* When given object version is a diff on some base, this method returns
|
|
@@ -102,7 +113,6 @@ export declare class ObjStatus implements SyncedObjStatus, UploadStatusRecorder
|
|
|
102
113
|
localBases?: number[];
|
|
103
114
|
syncedBase?: number;
|
|
104
115
|
} | undefined;
|
|
105
|
-
markLocalVersionSynced(localVersion: number, uploadVersion: number): Promise<void>;
|
|
106
116
|
setLocalCurrentVersion(version: number, baseVer: number | undefined): Promise<void>;
|
|
107
117
|
listVersions(): {
|
|
108
118
|
current?: number;
|
|
@@ -113,7 +123,9 @@ export declare class ObjStatus implements SyncedObjStatus, UploadStatusRecorder
|
|
|
113
123
|
latestSyncedVersion(): number | undefined;
|
|
114
124
|
syncStatus(): SyncStatus;
|
|
115
125
|
neverUploaded(): boolean;
|
|
126
|
+
versionBeforeUnsyncedRemoval(): number | undefined;
|
|
116
127
|
adoptRemoteVersion(version?: number, dropLocalVer?: boolean): Promise<void>;
|
|
128
|
+
isAmongRemote(version: number): boolean;
|
|
117
129
|
}
|
|
118
130
|
export declare function readAndCheckStatus(objFolder: string, objId: ObjId): Promise<ObjStatusInfo>;
|
|
119
131
|
export {};
|
|
@@ -22,6 +22,7 @@ const exceptions_1 = require("../../../lib-client/3nstorage/exceptions");
|
|
|
22
22
|
const json_saving_1 = require("../common/json-saving");
|
|
23
23
|
const obj_info_file_1 = require("../common/obj-info-file");
|
|
24
24
|
const assert_1 = require("../../../lib-common/assert");
|
|
25
|
+
const file_1 = require("../../../lib-common/exceptions/file");
|
|
25
26
|
function makeVersions() {
|
|
26
27
|
return {
|
|
27
28
|
baseToDiff: {},
|
|
@@ -81,12 +82,14 @@ function identifyNonGarbage(status) {
|
|
|
81
82
|
let uploadVersion = undefined;
|
|
82
83
|
if (status.local) {
|
|
83
84
|
local = nonGarbageWithMaxVer(status.local);
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
85
|
+
}
|
|
86
|
+
if (status.upload) {
|
|
87
|
+
const { localVersion } = status.upload;
|
|
88
|
+
if (status.local.current !== localVersion) {
|
|
89
|
+
(0, obj_info_file_1.addWithBasesTo)(local.nonGarbage, localVersion, status.local);
|
|
90
|
+
}
|
|
91
|
+
if (status.upload.type === 'new-version') {
|
|
92
|
+
uploadVersion = status.upload.uploadVersion;
|
|
90
93
|
}
|
|
91
94
|
}
|
|
92
95
|
const remote = nonGarbageWithMaxVer(status.remote);
|
|
@@ -136,6 +139,27 @@ class ObjStatus {
|
|
|
136
139
|
const status = await readAndCheckStatus(objFolder, objId);
|
|
137
140
|
return (syncStateOf(status) !== 'synced');
|
|
138
141
|
}
|
|
142
|
+
static async fileShowsObjNeedsRemovalOnRemote(objFolder, objId) {
|
|
143
|
+
const status = await readAndCheckStatus(objFolder, objId);
|
|
144
|
+
const upload = status.upload;
|
|
145
|
+
return (((upload === null || upload === void 0 ? void 0 : upload.type) === 'removal') && !upload.isPostponed);
|
|
146
|
+
}
|
|
147
|
+
needsRemovalOnRemote() {
|
|
148
|
+
const upload = this.status.upload;
|
|
149
|
+
return (((upload === null || upload === void 0 ? void 0 : upload.type) === 'removal') && !upload.isPostponed);
|
|
150
|
+
}
|
|
151
|
+
async clearPostponeFlagInRemovalOnRemote() {
|
|
152
|
+
const { upload } = this.status;
|
|
153
|
+
if (!upload) {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
if (upload.type !== 'removal') {
|
|
157
|
+
throw new Error(`No upload removal in obj status`);
|
|
158
|
+
}
|
|
159
|
+
upload.isPostponed = false;
|
|
160
|
+
await this.triggerSaveProc();
|
|
161
|
+
return true;
|
|
162
|
+
}
|
|
139
163
|
updateStateIndicator() {
|
|
140
164
|
this.stateIndicator = syncStateOf(this.status);
|
|
141
165
|
}
|
|
@@ -162,28 +186,36 @@ class ObjStatus {
|
|
|
162
186
|
return identifyNonGarbage(this.status);
|
|
163
187
|
}
|
|
164
188
|
async removeCurrentVersion() {
|
|
165
|
-
let { local, synced } = this.status;
|
|
189
|
+
let { local, synced, remote, upload } = this.status;
|
|
166
190
|
if ((synced === null || synced === void 0 ? void 0 : synced.isArchived) || (local === null || local === void 0 ? void 0 : local.isArchived)) {
|
|
167
191
|
return;
|
|
168
192
|
}
|
|
193
|
+
if (upload) {
|
|
194
|
+
if (upload.type === 'removal') {
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
throw (0, file_1.makeFileException)('concurrentUpdate', 'obj-status', `Upload is in progress`);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
if (!remote.isArchived && remote.current) {
|
|
202
|
+
this.status.upload = {
|
|
203
|
+
type: 'removal',
|
|
204
|
+
localVersion: ((local === null || local === void 0 ? void 0 : local.current) || (synced === null || synced === void 0 ? void 0 : synced.version)),
|
|
205
|
+
isPostponed: true
|
|
206
|
+
};
|
|
207
|
+
upload = this.status.upload;
|
|
208
|
+
}
|
|
169
209
|
if (local) {
|
|
170
|
-
|
|
210
|
+
local.isArchived = true;
|
|
211
|
+
local.current = undefined;
|
|
171
212
|
}
|
|
172
213
|
else {
|
|
173
|
-
local = makeVersions();
|
|
214
|
+
this.status.local = makeVersions();
|
|
215
|
+
this.status.local.isArchived = true;
|
|
174
216
|
}
|
|
175
|
-
local.isArchived = true;
|
|
176
217
|
this.updateStateIndicator();
|
|
177
|
-
;
|
|
178
|
-
await this.triggerSaveProc().catch((exc) => {
|
|
179
|
-
var _a;
|
|
180
|
-
if (exc.notFound && ((_a = this.status.local) === null || _a === void 0 ? void 0 : _a.isArchived)) {
|
|
181
|
-
return;
|
|
182
|
-
}
|
|
183
|
-
else {
|
|
184
|
-
throw exc;
|
|
185
|
-
}
|
|
186
|
-
});
|
|
218
|
+
await this.triggerSaveProc().catch(skipNotFoundExc);
|
|
187
219
|
}
|
|
188
220
|
async triggerSaveProc(captureErrors = false, logErr = false) {
|
|
189
221
|
try {
|
|
@@ -201,16 +233,17 @@ class ObjStatus {
|
|
|
201
233
|
}
|
|
202
234
|
}
|
|
203
235
|
recordUploadStart(info) {
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
236
|
+
var _a;
|
|
237
|
+
if (this.status.upload) {
|
|
238
|
+
const upload = this.status.upload;
|
|
207
239
|
throw (0, exceptions_1.makeFSSyncException)('obj-status', {
|
|
208
240
|
alreadyUploading: true,
|
|
209
|
-
message: `Status already has upload of version ${
|
|
241
|
+
message: `Status already has upload of version ${upload.uploadVersion} and can't start another upload with version ${info.uploadVersion}`
|
|
210
242
|
});
|
|
211
243
|
}
|
|
212
|
-
if (info.localVersion === local.current) {
|
|
213
|
-
|
|
244
|
+
if (info.localVersion === ((_a = this.status.local) === null || _a === void 0 ? void 0 : _a.current)) {
|
|
245
|
+
this.status.upload = info;
|
|
246
|
+
return this.triggerSaveProc();
|
|
214
247
|
}
|
|
215
248
|
else {
|
|
216
249
|
throw (0, exceptions_1.makeFSSyncException)('obj-status', {
|
|
@@ -218,22 +251,58 @@ class ObjStatus {
|
|
|
218
251
|
versionNotFound: true
|
|
219
252
|
});
|
|
220
253
|
}
|
|
221
|
-
return this.triggerSaveProc();
|
|
222
254
|
}
|
|
223
255
|
recordUploadInterimState(info) {
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
256
|
+
var _a;
|
|
257
|
+
if (((_a = this.status.upload) === null || _a === void 0 ? void 0 : _a.type) !== 'new-version') {
|
|
258
|
+
throw new Error(`No new version upload in object status`);
|
|
259
|
+
}
|
|
260
|
+
if (this.status.upload.uploadVersion === info.uploadVersion) {
|
|
261
|
+
this.status.upload = info;
|
|
262
|
+
return this.triggerSaveProc();
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
throw new Error(`Upload versions don't match`);
|
|
266
|
+
}
|
|
230
267
|
}
|
|
231
268
|
recordUploadCancellation(info) {
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
269
|
+
var _a;
|
|
270
|
+
if (((_a = this.status.upload) === null || _a === void 0 ? void 0 : _a.type) !== 'new-version') {
|
|
271
|
+
throw new Error(`No upload in object status`);
|
|
272
|
+
}
|
|
273
|
+
if (this.status.upload.uploadVersion === info.uploadVersion) {
|
|
274
|
+
this.status.upload = undefined;
|
|
275
|
+
return this.triggerSaveProc();
|
|
276
|
+
}
|
|
277
|
+
else {
|
|
278
|
+
throw new Error(`Upload versions don't match`);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
recordUploadCompletion(localVersion, uploadVersion) {
|
|
282
|
+
const { local, synced, remote, upload } = this.status;
|
|
283
|
+
if (((upload === null || upload === void 0 ? void 0 : upload.type) !== 'new-version')
|
|
284
|
+
|| (upload.uploadVersion !== uploadVersion)) {
|
|
285
|
+
throw new Error(`Upload versions don't match`);
|
|
286
|
+
}
|
|
287
|
+
const syncedBase = upload.baseVersion;
|
|
288
|
+
if (!remote.current || (remote.current <= uploadVersion)) {
|
|
289
|
+
(0, obj_info_file_1.setCurrentVersionIn)(remote, uploadVersion, syncedBase);
|
|
290
|
+
}
|
|
291
|
+
if (synced) {
|
|
292
|
+
synced.version = uploadVersion;
|
|
293
|
+
if (synced.base && (synced.base !== syncedBase)) {
|
|
294
|
+
(0, obj_info_file_1.rmNonArchVersionsIn)(remote, synced.base);
|
|
295
|
+
}
|
|
296
|
+
synced.base = syncedBase;
|
|
297
|
+
}
|
|
298
|
+
else {
|
|
299
|
+
this.status.synced = { version: uploadVersion, base: syncedBase };
|
|
300
|
+
}
|
|
301
|
+
if (local.current === localVersion) {
|
|
302
|
+
this.status.local = undefined;
|
|
303
|
+
}
|
|
304
|
+
this.status.upload = undefined;
|
|
305
|
+
this.updateStateIndicator();
|
|
237
306
|
return this.triggerSaveProc();
|
|
238
307
|
}
|
|
239
308
|
async recordArchVersionRemoval(version) {
|
|
@@ -256,31 +325,40 @@ class ObjStatus {
|
|
|
256
325
|
this.updateStateIndicator();
|
|
257
326
|
return this.triggerSaveProc();
|
|
258
327
|
}
|
|
259
|
-
async
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
328
|
+
async recordRemoteRemovalCompletion() {
|
|
329
|
+
var _a;
|
|
330
|
+
const { remote, upload, synced } = this.status;
|
|
331
|
+
if ((_a = this.status.synced) === null || _a === void 0 ? void 0 : _a.isArchived) {
|
|
263
332
|
return;
|
|
264
333
|
}
|
|
265
|
-
|
|
334
|
+
if ((upload === null || upload === void 0 ? void 0 : upload.type) !== 'removal') {
|
|
335
|
+
throw new Error(`Upload of removal is not in status`);
|
|
336
|
+
}
|
|
337
|
+
(0, obj_info_file_1.rmCurrentVersionIn)(remote);
|
|
338
|
+
remote.isArchived = true;
|
|
339
|
+
if (synced) {
|
|
340
|
+
synced.isArchived = true;
|
|
341
|
+
synced.version = undefined;
|
|
342
|
+
synced.base = undefined;
|
|
343
|
+
}
|
|
344
|
+
else {
|
|
345
|
+
this.status.synced = { isArchived: true };
|
|
346
|
+
}
|
|
347
|
+
this.status.local = undefined;
|
|
348
|
+
this.status.upload = undefined;
|
|
266
349
|
this.updateStateIndicator();
|
|
267
350
|
return this.triggerSaveProc();
|
|
268
351
|
}
|
|
269
|
-
|
|
270
|
-
this.status
|
|
271
|
-
(0
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
this.status.synced.isArchived = true;
|
|
275
|
-
this.status.synced.version = undefined;
|
|
276
|
-
if (this.status.synced.base) {
|
|
277
|
-
(0, obj_info_file_1.rmNonArchVersionsIn)(this.status.remote, this.status.synced.base);
|
|
278
|
-
this.status.synced.base = undefined;
|
|
279
|
-
}
|
|
352
|
+
async recordRemoteChange(version) {
|
|
353
|
+
const { synced, remote, upload } = this.status;
|
|
354
|
+
if (((upload === null || upload === void 0 ? void 0 : upload.type) === 'new-version')
|
|
355
|
+
&& (upload.uploadVersion === version)) {
|
|
356
|
+
return;
|
|
280
357
|
}
|
|
281
|
-
|
|
282
|
-
|
|
358
|
+
if ((synced === null || synced === void 0 ? void 0 : synced.version) && (synced.version >= version)) {
|
|
359
|
+
return;
|
|
283
360
|
}
|
|
361
|
+
remote.current = version;
|
|
284
362
|
this.updateStateIndicator();
|
|
285
363
|
return this.triggerSaveProc();
|
|
286
364
|
}
|
|
@@ -346,33 +424,6 @@ class ObjStatus {
|
|
|
346
424
|
return { localBases };
|
|
347
425
|
}
|
|
348
426
|
}
|
|
349
|
-
markLocalVersionSynced(localVersion, uploadVersion) {
|
|
350
|
-
const { local, synced, remote } = this.status;
|
|
351
|
-
(0, assert_1.assert)(!!(local === null || local === void 0 ? void 0 : local.upload) &&
|
|
352
|
-
((local === null || local === void 0 ? void 0 : local.upload.uploadVersion) === uploadVersion));
|
|
353
|
-
const syncedBase = local.upload.baseVersion;
|
|
354
|
-
if (!remote.current || (remote.current <= uploadVersion)) {
|
|
355
|
-
(0, obj_info_file_1.setCurrentVersionIn)(remote, uploadVersion, syncedBase);
|
|
356
|
-
}
|
|
357
|
-
if (synced) {
|
|
358
|
-
synced.version = uploadVersion;
|
|
359
|
-
if (synced.base && (synced.base !== syncedBase)) {
|
|
360
|
-
(0, obj_info_file_1.rmNonArchVersionsIn)(remote, synced.base);
|
|
361
|
-
}
|
|
362
|
-
synced.base = syncedBase;
|
|
363
|
-
}
|
|
364
|
-
else {
|
|
365
|
-
this.status.synced = { version: uploadVersion, base: syncedBase };
|
|
366
|
-
}
|
|
367
|
-
if (local.current === localVersion) {
|
|
368
|
-
this.status.local = undefined;
|
|
369
|
-
}
|
|
370
|
-
else {
|
|
371
|
-
local.upload = undefined;
|
|
372
|
-
}
|
|
373
|
-
this.updateStateIndicator();
|
|
374
|
-
return this.triggerSaveProc();
|
|
375
|
-
}
|
|
376
427
|
async setLocalCurrentVersion(version, baseVer) {
|
|
377
428
|
if (!this.status.local) {
|
|
378
429
|
this.status.local = makeVersions();
|
|
@@ -446,6 +497,15 @@ class ObjStatus {
|
|
|
446
497
|
const synced = this.status.synced;
|
|
447
498
|
return (!(synced === null || synced === void 0 ? void 0 : synced.version) && !(synced === null || synced === void 0 ? void 0 : synced.isArchived));
|
|
448
499
|
}
|
|
500
|
+
versionBeforeUnsyncedRemoval() {
|
|
501
|
+
var _a;
|
|
502
|
+
if ((this.stateIndicator !== 'synced')
|
|
503
|
+
&& ((_a = this.status.local) === null || _a === void 0 ? void 0 : _a.isArchived)
|
|
504
|
+
&& this.status.upload
|
|
505
|
+
&& (this.status.upload.type === 'removal')) {
|
|
506
|
+
return this.status.upload.localVersion;
|
|
507
|
+
}
|
|
508
|
+
}
|
|
449
509
|
async adoptRemoteVersion(version, dropLocalVer = false) {
|
|
450
510
|
var _a;
|
|
451
511
|
const { local, remote } = this.status;
|
|
@@ -491,6 +551,16 @@ class ObjStatus {
|
|
|
491
551
|
this.updateStateIndicator();
|
|
492
552
|
await this.triggerSaveProc();
|
|
493
553
|
}
|
|
554
|
+
isAmongRemote(version) {
|
|
555
|
+
var _a;
|
|
556
|
+
if (this.status.remote.current === version) {
|
|
557
|
+
return true;
|
|
558
|
+
}
|
|
559
|
+
if ((_a = this.status.remote.archived) === null || _a === void 0 ? void 0 : _a.includes(version)) {
|
|
560
|
+
return true;
|
|
561
|
+
}
|
|
562
|
+
return false;
|
|
563
|
+
}
|
|
494
564
|
}
|
|
495
565
|
exports.ObjStatus = ObjStatus;
|
|
496
566
|
Object.freeze(ObjStatus.prototype);
|
|
@@ -596,4 +666,9 @@ function addArchVersionsFromList(remote, existingVersions) {
|
|
|
596
666
|
}
|
|
597
667
|
return isAnythingChanged;
|
|
598
668
|
}
|
|
669
|
+
function skipNotFoundExc(exc) {
|
|
670
|
+
if (!exc.notFound) {
|
|
671
|
+
throw exc;
|
|
672
|
+
}
|
|
673
|
+
}
|
|
599
674
|
Object.freeze(exports);
|
|
@@ -15,7 +15,7 @@ export declare class SyncedStore implements ISyncedStorage {
|
|
|
15
15
|
private readonly remoteStorage;
|
|
16
16
|
private readonly getStorages;
|
|
17
17
|
readonly cryptor: AsyncSBoxCryptor;
|
|
18
|
-
|
|
18
|
+
readonly logError: LogError;
|
|
19
19
|
readonly type: web3n.files.FSType;
|
|
20
20
|
readonly versioned = true;
|
|
21
21
|
readonly nodes: NodesContainer;
|
|
@@ -27,12 +27,17 @@ export declare class SyncedStore implements ISyncedStorage {
|
|
|
27
27
|
syncedStore: ISyncedStorage;
|
|
28
28
|
startObjProcs: () => void;
|
|
29
29
|
}>;
|
|
30
|
+
static makeAndStartWithoutRemote(path: string, user: string, getStorages: StorageGetter, cryptor: AsyncSBoxCryptor, remoteServiceUrl: () => Promise<string>, net: NetClient, logError: LogError): Promise<{
|
|
31
|
+
syncedStore: ISyncedStorage;
|
|
32
|
+
setupRemoteAndStartObjProcs: (getSigner: IGetMailerIdSigner) => void;
|
|
33
|
+
}>;
|
|
30
34
|
getNodeEvents(): Observable<NodeEvent>;
|
|
31
35
|
broadcastNodeEvent(objId: ObjId, parentObjId: ObjId | undefined, childObjId: ObjId | undefined, event: FolderEvent | FileEvent): void;
|
|
32
36
|
storageForLinking(type: web3n.files.FSType, location?: string): IStorage;
|
|
33
37
|
status(objId: ObjId): Promise<SyncedObjStatus>;
|
|
34
38
|
adoptRemote(objId: ObjId, opts: OptionsToAdopteRemote | undefined): Promise<number | undefined>;
|
|
35
39
|
updateStatusInfo(objId: ObjId): Promise<SyncStatus>;
|
|
40
|
+
isObjOnDisk(objId: ObjId): Promise<boolean>;
|
|
36
41
|
isRemoteVersionOnDisk(objId: ObjId, version: number): Promise<'complete' | 'partial' | 'none'>;
|
|
37
42
|
download(objId: ObjId, version: number): Promise<void>;
|
|
38
43
|
upload(objId: ObjId, localVersion: number, uploadVersion: number, uploadHeader: UploadHeaderChange | undefined, createOnRemote: boolean): Promise<void>;
|
|
@@ -43,7 +48,7 @@ export declare class SyncedStore implements ISyncedStorage {
|
|
|
43
48
|
generateNewObjId(): Promise<string>;
|
|
44
49
|
private objFromDiskOrDownload;
|
|
45
50
|
private getObjOrThrow;
|
|
46
|
-
getObjSrc(objId: ObjId, version?: number): Promise<ObjSource>;
|
|
51
|
+
getObjSrc(objId: ObjId, version?: number, allowArchived?: boolean): Promise<ObjSource>;
|
|
47
52
|
getObjSrcOfRemoteVersion(objId: ObjId, version: number): Promise<ObjSource>;
|
|
48
53
|
saveObj(objId: ObjId, version: number, encSub: Subscribe): Promise<void>;
|
|
49
54
|
removeObj(objId: string): Promise<void>;
|
|
@@ -43,7 +43,7 @@ class SyncedStore {
|
|
|
43
43
|
Object.seal(this);
|
|
44
44
|
}
|
|
45
45
|
static async makeAndStart(path, user, getSigner, getStorages, cryptor, remoteServiceUrl, net, logError) {
|
|
46
|
-
const remote =
|
|
46
|
+
const remote = service_1.StorageOwner.make(user, getSigner, remoteServiceUrl, net);
|
|
47
47
|
const objFiles = await obj_files_1.ObjFiles.makeFor(path, remote, logError);
|
|
48
48
|
const s = new SyncedStore(objFiles, remote, getStorages, cryptor, logError);
|
|
49
49
|
s.uploader.start();
|
|
@@ -54,6 +54,19 @@ class SyncedStore {
|
|
|
54
54
|
}
|
|
55
55
|
};
|
|
56
56
|
}
|
|
57
|
+
static async makeAndStartWithoutRemote(path, user, getStorages, cryptor, remoteServiceUrl, net, logError) {
|
|
58
|
+
const { remote, setMid } = service_1.StorageOwner.makeBeforeMidSetup(user, remoteServiceUrl, net);
|
|
59
|
+
const objFiles = await obj_files_1.ObjFiles.makeFor(path, remote, logError);
|
|
60
|
+
const s = new SyncedStore(objFiles, remote, getStorages, cryptor, logError);
|
|
61
|
+
return {
|
|
62
|
+
syncedStore: (0, common_1.wrapSyncStorageImplementation)(s),
|
|
63
|
+
setupRemoteAndStartObjProcs: getSigner => {
|
|
64
|
+
setMid(getSigner);
|
|
65
|
+
s.uploader.start();
|
|
66
|
+
s.remoteEvents.startAbsorbingRemoteEvents();
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
}
|
|
57
70
|
getNodeEvents() {
|
|
58
71
|
return this.events.event$;
|
|
59
72
|
}
|
|
@@ -72,7 +85,7 @@ class SyncedStore {
|
|
|
72
85
|
}
|
|
73
86
|
}
|
|
74
87
|
async status(objId) {
|
|
75
|
-
const obj = await this.getObjOrThrow(objId);
|
|
88
|
+
const obj = await this.getObjOrThrow(objId, true);
|
|
76
89
|
return obj.syncStatus();
|
|
77
90
|
}
|
|
78
91
|
async adoptRemote(objId, opts) {
|
|
@@ -81,6 +94,7 @@ class SyncedStore {
|
|
|
81
94
|
await objStatus.adoptRemoteVersion(opts === null || opts === void 0 ? void 0 : opts.remoteVersion, opts === null || opts === void 0 ? void 0 : opts.dropLocalVer);
|
|
82
95
|
if (opts && opts.download) {
|
|
83
96
|
// XXX this needs implementation
|
|
97
|
+
throw new Error('SyncedStore.adoptRemote() with download option needs implementation, probably using SyncedStore.download().');
|
|
84
98
|
}
|
|
85
99
|
this.files.scheduleGC(obj);
|
|
86
100
|
return objStatus.syncStatus().synced.latest;
|
|
@@ -103,17 +117,17 @@ class SyncedStore {
|
|
|
103
117
|
throw exc;
|
|
104
118
|
}
|
|
105
119
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
// - get state of file
|
|
110
|
-
// But, should this be renamed to isRemoteVersionOnDisk ?
|
|
111
|
-
//
|
|
112
|
-
throw new Error('SyncedStore.isRemoteVersionOnDisk() not implemented.');
|
|
120
|
+
async isObjOnDisk(objId) {
|
|
121
|
+
const obj = await this.files.findObj(objId);
|
|
122
|
+
return !!obj;
|
|
113
123
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
124
|
+
async isRemoteVersionOnDisk(objId, version) {
|
|
125
|
+
const obj = await this.getObjOrThrow(objId, true);
|
|
126
|
+
return obj.isRemoteVersionOnDisk(version);
|
|
127
|
+
}
|
|
128
|
+
async download(objId, version) {
|
|
129
|
+
const obj = await this.getObjOrThrow(objId, true);
|
|
130
|
+
return obj.downloadRemoteVersion(version);
|
|
117
131
|
}
|
|
118
132
|
async upload(objId, localVersion, uploadVersion, uploadHeader, createOnRemote) {
|
|
119
133
|
const obj = await this.getObjOrThrow(objId, true);
|
|
@@ -134,7 +148,14 @@ class SyncedStore {
|
|
|
134
148
|
if (!objId) {
|
|
135
149
|
return;
|
|
136
150
|
}
|
|
137
|
-
await this.
|
|
151
|
+
const obj = await this.getObjOrThrow(objId, true);
|
|
152
|
+
const status = obj.statusObj();
|
|
153
|
+
if (status.neverUploaded()) {
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
if (await status.clearPostponeFlagInRemovalOnRemote()) {
|
|
157
|
+
await this.uploader.removeCurrentVersionOf(obj);
|
|
158
|
+
}
|
|
138
159
|
}
|
|
139
160
|
dropCachedLocalObjVersionsLessOrEqual(objId, version) {
|
|
140
161
|
const obj = this.files.getObjInCache(objId);
|
|
@@ -164,6 +185,8 @@ class SyncedStore {
|
|
|
164
185
|
if (obj) {
|
|
165
186
|
return obj;
|
|
166
187
|
}
|
|
188
|
+
// XXX
|
|
189
|
+
// - can we create object by getting obj status
|
|
167
190
|
return await this.files.makeByDownloadingCurrentVersion(objId);
|
|
168
191
|
}
|
|
169
192
|
async getObjOrThrow(objId, allowArchived = false) {
|
|
@@ -175,8 +198,8 @@ class SyncedStore {
|
|
|
175
198
|
return obj;
|
|
176
199
|
}
|
|
177
200
|
}
|
|
178
|
-
async getObjSrc(objId, version) {
|
|
179
|
-
const obj = await this.getObjOrThrow(objId);
|
|
201
|
+
async getObjSrc(objId, version, allowArchived = false) {
|
|
202
|
+
const obj = await this.getObjOrThrow(objId, allowArchived);
|
|
180
203
|
if (!version) {
|
|
181
204
|
version = obj.statusObj().getCurrentLocalOrSynced();
|
|
182
205
|
}
|
|
@@ -3,7 +3,7 @@ import { SyncedObj } from "./obj-files";
|
|
|
3
3
|
import { MonoTypeOperatorFunction } from "rxjs";
|
|
4
4
|
import { FileWrite } from "../../../lib-client/objs-on-disk/file-writing-proc";
|
|
5
5
|
import { LogError } from "../../../lib-client/logging/log-to-file";
|
|
6
|
-
import {
|
|
6
|
+
import { NewVersionUpload } from "./obj-status";
|
|
7
7
|
export declare type FileWriteTapOperator = MonoTypeOperatorFunction<FileWrite[]>;
|
|
8
8
|
export declare class UpSyncer {
|
|
9
9
|
private readonly remoteStorage;
|
|
@@ -21,7 +21,7 @@ export declare class UpSyncer {
|
|
|
21
21
|
uploadFromDisk(obj: SyncedObj, localVersion: number, uploadVersion: number, uploadHeader: Uint8Array | undefined, syncedBase: number | undefined, createOnRemote: boolean): Promise<void>;
|
|
22
22
|
}
|
|
23
23
|
export interface UploadStatusRecorder {
|
|
24
|
-
recordUploadStart(info:
|
|
25
|
-
recordUploadCancellation(info:
|
|
26
|
-
recordUploadInterimState(info:
|
|
24
|
+
recordUploadStart(info: NewVersionUpload): Promise<void>;
|
|
25
|
+
recordUploadCancellation(info: NewVersionUpload): Promise<void>;
|
|
26
|
+
recordUploadInterimState(info: NewVersionUpload): Promise<void>;
|
|
27
27
|
}
|
|
@@ -50,12 +50,17 @@ class UpSyncer {
|
|
|
50
50
|
// return objUploads.tapFileWrite(isNew, newVersion, baseVersion);
|
|
51
51
|
}
|
|
52
52
|
async removeCurrentVersionOf(obj) {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
53
|
+
try {
|
|
54
|
+
await this.remoteStorage.deleteObj(obj.objId);
|
|
55
|
+
}
|
|
56
|
+
catch (exc) {
|
|
57
|
+
// XXX
|
|
58
|
+
// - we need to distinguish errors and put this work somewhere
|
|
59
|
+
// to run when we go online, for example.
|
|
60
|
+
await this.logError(exc, `Uploading of obj removal failed.`);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
await obj.recordRemovalUploadAndGC();
|
|
59
64
|
}
|
|
60
65
|
async uploadFromDisk(obj, localVersion, uploadVersion, uploadHeader, syncedBase, createOnRemote) {
|
|
61
66
|
const task = await UploadTask.for(obj, localVersion, uploadVersion, uploadHeader, syncedBase, createOnRemote, this.remoteStorage, this.execPools);
|
|
@@ -90,6 +95,7 @@ class UploadTask {
|
|
|
90
95
|
needUpload = await wholeVerUpload(src, uploadHeader, createObj);
|
|
91
96
|
}
|
|
92
97
|
const info = {
|
|
98
|
+
type: 'new-version',
|
|
93
99
|
localVersion,
|
|
94
100
|
uploadVersion,
|
|
95
101
|
baseVersion: syncedBase,
|
|
@@ -160,13 +166,12 @@ class UploadTask {
|
|
|
160
166
|
}
|
|
161
167
|
(0, assert_1.assert)(!!segs && (segs.length === segsToUpload));
|
|
162
168
|
const ver = this.info.uploadVersion;
|
|
163
|
-
const create = (upload.createObj ? true : undefined);
|
|
164
169
|
if (segsToUpload === upload.segsLeft) {
|
|
165
|
-
await this.remoteStorage.saveNewObjVersion(this.objId, { ver,
|
|
170
|
+
await this.remoteStorage.saveNewObjVersion(this.objId, { ver, last: true }, undefined, { header, segs });
|
|
166
171
|
this.info.needUpload = undefined;
|
|
167
172
|
}
|
|
168
173
|
else {
|
|
169
|
-
upload.transactionId = await this.remoteStorage.saveNewObjVersion(this.objId, { ver
|
|
174
|
+
upload.transactionId = await this.remoteStorage.saveNewObjVersion(this.objId, { ver }, undefined, { header, segs });
|
|
170
175
|
if (!upload.transactionId) {
|
|
171
176
|
// XXX should this be runtime exception saying that remote acts badly ?
|
|
172
177
|
throw new Error(`Server didn't start obj saving transaction`);
|
|
@@ -14,6 +14,7 @@ declare type FileEvent = web3n.files.FileEvent;
|
|
|
14
14
|
declare type RemoteEvent = web3n.files.RemoteEvent;
|
|
15
15
|
declare type OptionsToAdopteRemote = web3n.files.OptionsToAdopteRemote;
|
|
16
16
|
declare type OptionsToUploadLocal = web3n.files.OptionsToUploadLocal;
|
|
17
|
+
declare type VersionedReadFlags = web3n.files.VersionedReadFlags;
|
|
17
18
|
export declare function makeFileCaller(caller: Caller, fileMsg: FileMsg): File;
|
|
18
19
|
export declare function exposeFileService(file: File, expServices: ExposedServices): FileMsg;
|
|
19
20
|
export interface FileMsg {
|
|
@@ -41,6 +42,12 @@ export declare function packJSON(json: any): EnvelopeBody;
|
|
|
41
42
|
export declare function unpackJSON(buf: EnvelopeBody): any;
|
|
42
43
|
export declare function packFileEvent(e: FileEvent | RemoteEvent): Buffer;
|
|
43
44
|
export declare function unpackFileEvent(buf: EnvelopeBody): FileEvent | RemoteEvent;
|
|
45
|
+
export interface VersionedReadFlagsMsg {
|
|
46
|
+
archivedVersion?: Value<number>;
|
|
47
|
+
remoteVersion?: Value<number>;
|
|
48
|
+
}
|
|
49
|
+
export declare function versionedReadFlagsFromMsg(msg: VersionedReadFlagsMsg | undefined): VersionedReadFlags | undefined;
|
|
50
|
+
export declare function versionedReadFlagsToMsg(flags: VersionedReadFlags | undefined): VersionedReadFlagsMsg | undefined;
|
|
44
51
|
export declare namespace vGetXAttr {
|
|
45
52
|
interface Reply {
|
|
46
53
|
version: number;
|