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
|
@@ -1,36 +1,29 @@
|
|
|
1
1
|
import { Observable } from 'rxjs';
|
|
2
|
-
import { ObjId } from '../../../lib-client/3nstorage/xsp-fs/common';
|
|
2
|
+
import { ObjId, SyncedObjStatus } from '../../../lib-client/3nstorage/xsp-fs/common';
|
|
3
3
|
import { InitDownloadParts } from '../../../lib-client/objs-on-disk/obj-on-disk';
|
|
4
4
|
import { ObjSource, Subscribe } from 'xsp-files';
|
|
5
5
|
import { Downloader } from './downloader';
|
|
6
6
|
import { FileWrite } from '../../../lib-client/objs-on-disk/file-writing-proc';
|
|
7
7
|
import { GC } from './obj-files-gc';
|
|
8
|
+
import { ObjStatus } from './obj-status';
|
|
8
9
|
import { LogError } from '../../../lib-client/logging/log-to-file';
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
import { DiffInfo } from '../../../lib-common/service-api/3nstorage/owner';
|
|
11
|
+
import { FiniteChunk } from '../../../lib-common/objs-on-disk/file-layout';
|
|
12
|
+
import { StorageOwner as RemoteStorage } from '../../../lib-client/3nstorage/service';
|
|
13
|
+
import { UploadHeaderChange } from '../../../lib-client/3nstorage/xsp-fs/common';
|
|
13
14
|
export declare const UNSYNCED_FILE_NAME_EXT = "unsynced";
|
|
14
|
-
|
|
15
|
-
* This is an upload info file. When an upload is complete,
|
|
16
|
-
* this info file is removed.
|
|
17
|
-
*/
|
|
18
|
-
export declare const UPLOAD_INFO_FNAME = "upload";
|
|
19
|
-
/**
|
|
20
|
-
* Presence of this empty file in a object folder indicates that object's
|
|
21
|
-
* removal hasn't been synchronized, yet.
|
|
22
|
-
*/
|
|
23
|
-
export declare const UNSYNCED_REMOVAL = "unsynced-removal";
|
|
15
|
+
export declare const REMOTE_FILE_NAME_EXT = "v";
|
|
24
16
|
export declare class ObjFiles {
|
|
25
17
|
private readonly folders;
|
|
26
|
-
private readonly downloader;
|
|
27
18
|
private readonly logError;
|
|
28
19
|
private readonly objs;
|
|
29
20
|
private readonly sync;
|
|
21
|
+
private readonly downloader;
|
|
30
22
|
private readonly gc;
|
|
31
23
|
private constructor();
|
|
32
|
-
static makeFor(path: string,
|
|
24
|
+
static makeFor(path: string, remote: RemoteStorage, logError: LogError): Promise<ObjFiles>;
|
|
33
25
|
findObj(objId: ObjId): Promise<SyncedObj | undefined>;
|
|
26
|
+
getObjInCache(objId: ObjId): SyncedObj | undefined;
|
|
34
27
|
private makeObj;
|
|
35
28
|
private removeFailedNewObj;
|
|
36
29
|
makeByDownloadingCurrentVersion(objId: ObjId): Promise<SyncedObj>;
|
|
@@ -38,7 +31,8 @@ export declare class ObjFiles {
|
|
|
38
31
|
fileWrite$: Observable<FileWrite[]>;
|
|
39
32
|
newObj: SyncedObj;
|
|
40
33
|
}>;
|
|
41
|
-
|
|
34
|
+
findUnsyncedObjs(): Observable<ObjId>;
|
|
35
|
+
scheduleGC(obj: SyncedObj): void;
|
|
42
36
|
}
|
|
43
37
|
export declare type SynchronizerOnObjId = <T>(objId: ObjId, action: () => Promise<T>) => Promise<T>;
|
|
44
38
|
export declare class SyncedObj {
|
|
@@ -47,39 +41,44 @@ export declare class SyncedObj {
|
|
|
47
41
|
private readonly status;
|
|
48
42
|
private readonly downloader;
|
|
49
43
|
private readonly scheduleGC;
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
* object's versions. Versions here can be either synced, or unsynced.
|
|
53
|
-
*/
|
|
54
|
-
private readonly verObjs;
|
|
55
|
-
/**
|
|
56
|
-
* These are conflicting versions, coming from a server. Of course, universal
|
|
57
|
-
* truth is spread by server, but in situations of parallel changes, local
|
|
58
|
-
* version allows things to work, while conflicting version from server
|
|
59
|
-
* should be adopted by conflict resolution process. In other words, these
|
|
60
|
-
* versions are not for common use.
|
|
61
|
-
*/
|
|
62
|
-
private readonly remoteConflictVerObjs;
|
|
44
|
+
private readonly remoteVers;
|
|
45
|
+
private readonly localVers;
|
|
63
46
|
private constructor();
|
|
64
|
-
static forExistingObj(objId: ObjId, objFolder: string, downloader: Downloader, scheduleGC: GC['scheduleCollection']): Promise<SyncedObj>;
|
|
65
|
-
static forDownloadedObj(objId: ObjId, objFolder: string, downloader: Downloader, scheduleGC: GC['scheduleCollection'], version: number, parts: InitDownloadParts): Promise<SyncedObj>;
|
|
66
|
-
static forNewObj(objId: ObjId, objFolder: string, downloader: Downloader, scheduleGC: GC['scheduleCollection']): Promise<SyncedObj>;
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
private
|
|
70
|
-
|
|
71
|
-
|
|
47
|
+
static forExistingObj(objId: ObjId, objFolder: string, downloader: Downloader, scheduleGC: GC['scheduleCollection'], logError: LogError): Promise<SyncedObj>;
|
|
48
|
+
static forDownloadedObj(objId: ObjId, objFolder: string, downloader: Downloader, scheduleGC: GC['scheduleCollection'], version: number, parts: InitDownloadParts, logError: LogError): Promise<SyncedObj>;
|
|
49
|
+
static forNewObj(objId: ObjId, objFolder: string, downloader: Downloader, scheduleGC: GC['scheduleCollection'], logError: LogError): Promise<SyncedObj>;
|
|
50
|
+
scheduleSelfGC(): void;
|
|
51
|
+
private localVerPath;
|
|
52
|
+
private remoteVerPath;
|
|
53
|
+
getObjSrcFromLocalAndSyncedBranch(version: number): Promise<ObjSource>;
|
|
54
|
+
getObjSrcFromRemoteAndSyncedBranch(version: number): Promise<ObjSource>;
|
|
55
|
+
private instanceOfLocalObjVer;
|
|
56
|
+
private instanceOfRemoteObjVer;
|
|
57
|
+
private readonly localAndSyncedObjSegsGetterFromDisk;
|
|
58
|
+
private readonly remoteObjSegsGetterFromDisk;
|
|
72
59
|
saveNewVersion(version: number, encSub: Subscribe): Promise<{
|
|
73
60
|
fileWrite$: Observable<FileWrite[]>;
|
|
74
61
|
baseVer?: number;
|
|
75
62
|
}>;
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
63
|
+
combineLocalBaseIfPresent(version: number): Promise<number | undefined>;
|
|
64
|
+
saveUploadHeaderFile(uploadHeader: UploadHeaderChange): Promise<void>;
|
|
65
|
+
private setUnsyncedCurrentVersion;
|
|
66
|
+
/**
|
|
67
|
+
* This renames/moves version file from local to remote.
|
|
68
|
+
* Removes upload info from status, updating enumerations of local and
|
|
69
|
+
* synced versions.
|
|
70
|
+
*/
|
|
71
|
+
recordUploadCompletion(localVersion: number, uploadVersion: number, headerChange: {
|
|
72
|
+
newHeader: Uint8Array;
|
|
73
|
+
originalHeader: Uint8Array;
|
|
74
|
+
} | undefined): Promise<void>;
|
|
75
|
+
dropCachedLocalObjVersionsLessOrEqual(version: number): void;
|
|
76
|
+
removeLocalVersionFilesLessThan(version: number): Promise<void>;
|
|
84
77
|
removeCurrentVersion(): Promise<void>;
|
|
78
|
+
diffForUploadOf(version: number): Promise<{
|
|
79
|
+
diff: DiffInfo;
|
|
80
|
+
newSegsPackOrder: FiniteChunk[];
|
|
81
|
+
}>;
|
|
82
|
+
syncStatus(): SyncedObjStatus;
|
|
83
|
+
statusObj(): ObjStatus;
|
|
85
84
|
}
|
|
@@ -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
|
|
@@ -16,64 +16,59 @@
|
|
|
16
16
|
this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
17
|
*/
|
|
18
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
-
exports.SyncedObj = exports.ObjFiles = exports.
|
|
19
|
+
exports.SyncedObj = exports.ObjFiles = exports.REMOTE_FILE_NAME_EXT = exports.UNSYNCED_FILE_NAME_EXT = void 0;
|
|
20
20
|
const rxjs_1 = require("rxjs");
|
|
21
|
-
const
|
|
21
|
+
const synced_1 = require("../../../lib-common/processes/synced");
|
|
22
|
+
const sleep_1 = require("../../../lib-common/processes/sleep");
|
|
22
23
|
const obj_folders_1 = require("../../../lib-client/objs-on-disk/obj-folders");
|
|
23
24
|
const fs = require("../../../lib-common/async-fs-node");
|
|
24
25
|
const obj_on_disk_1 = require("../../../lib-client/objs-on-disk/obj-on-disk");
|
|
25
26
|
const path_1 = require("path");
|
|
27
|
+
const downloader_1 = require("./downloader");
|
|
26
28
|
const assert_1 = require("../../../lib-common/assert");
|
|
27
29
|
const operators_1 = require("rxjs/operators");
|
|
28
30
|
const utils_for_observables_1 = require("../../../lib-common/utils-for-observables");
|
|
29
31
|
const obj_files_gc_1 = require("./obj-files-gc");
|
|
30
32
|
const obj_status_1 = require("./obj-status");
|
|
31
33
|
const timed_cache_1 = require("../../../lib-common/timed-cache");
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
* version number.
|
|
35
|
-
*/
|
|
34
|
+
const upload_header_file_1 = require("./upload-header-file");
|
|
35
|
+
const utils_1 = require("../common/utils");
|
|
36
36
|
exports.UNSYNCED_FILE_NAME_EXT = 'unsynced';
|
|
37
|
-
|
|
38
|
-
* This is an upload info file. When an upload is complete,
|
|
39
|
-
* this info file is removed.
|
|
40
|
-
*/
|
|
41
|
-
exports.UPLOAD_INFO_FNAME = 'upload';
|
|
42
|
-
/**
|
|
43
|
-
* Presence of this empty file in a object folder indicates that object's
|
|
44
|
-
* removal hasn't been synchronized, yet.
|
|
45
|
-
*/
|
|
46
|
-
exports.UNSYNCED_REMOVAL = 'unsynced-removal';
|
|
37
|
+
exports.REMOTE_FILE_NAME_EXT = 'v';
|
|
47
38
|
class ObjFiles {
|
|
48
|
-
constructor(folders,
|
|
39
|
+
constructor(folders, remote, logError) {
|
|
49
40
|
this.folders = folders;
|
|
50
|
-
this.downloader = downloader;
|
|
51
41
|
this.logError = logError;
|
|
52
|
-
this.objs = timed_cache_1.makeTimedCache(60 * 1000);
|
|
42
|
+
this.objs = (0, timed_cache_1.makeTimedCache)(60 * 1000);
|
|
53
43
|
this.sync = makeSynchronizer();
|
|
44
|
+
this.downloader = new downloader_1.Downloader(remote);
|
|
54
45
|
this.gc = new obj_files_gc_1.GC(this.sync, obj => {
|
|
55
46
|
if (this.objs.get(obj.objId) === obj) {
|
|
56
47
|
this.objs.delete(obj.objId);
|
|
57
48
|
}
|
|
58
|
-
}, objId => this.folders.removeFolderOf(objId));
|
|
49
|
+
}, objId => this.folders.removeFolderOf(objId), remote);
|
|
59
50
|
Object.freeze(this);
|
|
60
51
|
}
|
|
61
|
-
static async makeFor(path,
|
|
62
|
-
const
|
|
52
|
+
static async makeFor(path, remote, logError) {
|
|
53
|
+
const canMove = async (objId, objFolderPath) => {
|
|
63
54
|
if (objFiles.objs.has(objId)) {
|
|
64
55
|
return false;
|
|
65
56
|
}
|
|
66
57
|
const lst = await fs.readdir(objFolderPath);
|
|
67
58
|
for (const fName of lst) {
|
|
68
|
-
if (fName.endsWith(exports.UNSYNCED_FILE_NAME_EXT)
|
|
69
|
-
|| (fName === exports.UPLOAD_INFO_FNAME)
|
|
70
|
-
|| (fName === exports.UNSYNCED_REMOVAL)) {
|
|
59
|
+
if (fName.endsWith(exports.UNSYNCED_FILE_NAME_EXT)) {
|
|
71
60
|
return false;
|
|
72
61
|
}
|
|
73
62
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
63
|
+
try {
|
|
64
|
+
return (await obj_status_1.ObjStatus.fileShowsObjNotInSyncedState(objFolderPath, objId));
|
|
65
|
+
}
|
|
66
|
+
catch (exc) {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
const folders = await obj_folders_1.ObjFolders.makeWithGenerations(path, canMove, logError);
|
|
71
|
+
const objFiles = new ObjFiles(folders, remote, logError);
|
|
77
72
|
return objFiles;
|
|
78
73
|
}
|
|
79
74
|
async findObj(objId) {
|
|
@@ -86,21 +81,24 @@ class ObjFiles {
|
|
|
86
81
|
if (!folder) {
|
|
87
82
|
return;
|
|
88
83
|
}
|
|
89
|
-
const obj = await SyncedObj.forExistingObj(objId, folder, this.downloader, this.gc.scheduleCollection);
|
|
84
|
+
const obj = await SyncedObj.forExistingObj(objId, folder, this.downloader, this.gc.scheduleCollection, this.logError);
|
|
90
85
|
this.objs.set(objId, obj);
|
|
91
86
|
return obj;
|
|
92
87
|
});
|
|
93
88
|
}
|
|
89
|
+
getObjInCache(objId) {
|
|
90
|
+
return this.objs.get(objId);
|
|
91
|
+
}
|
|
94
92
|
makeObj(objId, download) {
|
|
95
93
|
return this.sync(objId, async () => {
|
|
96
94
|
const folder = await this.folders.getFolderAccessFor(objId, true);
|
|
97
95
|
let obj;
|
|
98
96
|
if (download) {
|
|
99
|
-
assert_1.assert(typeof download.version === 'number');
|
|
100
|
-
obj = await SyncedObj.forDownloadedObj(objId, folder, this.downloader, this.gc.scheduleCollection, download.version, download.parts);
|
|
97
|
+
(0, assert_1.assert)(typeof download.version === 'number');
|
|
98
|
+
obj = await SyncedObj.forDownloadedObj(objId, folder, this.downloader, this.gc.scheduleCollection, download.version, download.parts, this.logError);
|
|
101
99
|
}
|
|
102
100
|
else {
|
|
103
|
-
obj = await SyncedObj.forNewObj(objId, folder, this.downloader, this.gc.scheduleCollection);
|
|
101
|
+
obj = await SyncedObj.forNewObj(objId, folder, this.downloader, this.gc.scheduleCollection, this.logError);
|
|
104
102
|
}
|
|
105
103
|
this.objs.set(objId, obj);
|
|
106
104
|
return obj;
|
|
@@ -117,6 +115,10 @@ class ObjFiles {
|
|
|
117
115
|
return;
|
|
118
116
|
});
|
|
119
117
|
}
|
|
118
|
+
// XXX we'll need getting archived version.
|
|
119
|
+
// Getting current may be changed to grub info about all obj versions.
|
|
120
|
+
// As currently this.makeByDownloadingCurrentVersion() makes assumptions.
|
|
121
|
+
// Should it be a pattern: version not in status -> get info first.
|
|
120
122
|
async makeByDownloadingCurrentVersion(objId) {
|
|
121
123
|
// initial download implicitly checks existence of obj on server
|
|
122
124
|
const download = await this.downloader.getCurrentObjVersion(objId);
|
|
@@ -126,28 +128,31 @@ class ObjFiles {
|
|
|
126
128
|
async saveFirstVersion(objId, encSub) {
|
|
127
129
|
const newObj = await this.makeObj(objId);
|
|
128
130
|
const fileWrite$ = (await newObj.saveNewVersion(1, encSub)).fileWrite$
|
|
129
|
-
.pipe(utils_for_observables_1.flatTap(undefined, err => this.removeFailedNewObj(newObj)));
|
|
131
|
+
.pipe((0, utils_for_observables_1.flatTap)(undefined, err => this.removeFailedNewObj(newObj)));
|
|
130
132
|
return { fileWrite$, newObj };
|
|
131
133
|
}
|
|
132
|
-
|
|
133
|
-
return rxjs_1.from([undefined])
|
|
134
|
+
findUnsyncedObjs() {
|
|
135
|
+
return (0, rxjs_1.from)([undefined])
|
|
134
136
|
.pipe(
|
|
135
137
|
// listing recent folders, exactly once
|
|
136
|
-
operators_1.mergeMap(() => this.folders.listRecent()),
|
|
138
|
+
(0, operators_1.mergeMap)(() => this.folders.listRecent()),
|
|
137
139
|
// flatten array and space it in time, to process folders one by one
|
|
138
|
-
operators_1.mergeMap(objsAndPaths => objsAndPaths), operators_1.filter(({ objId }) => !this.objs.has(objId)), operators_1.mergeMap(async (objsAndPaths) => {
|
|
139
|
-
await
|
|
140
|
+
(0, operators_1.mergeMap)(objsAndPaths => objsAndPaths), (0, operators_1.filter)(({ objId }) => !this.objs.has(objId)), (0, operators_1.mergeMap)(async (objsAndPaths) => {
|
|
141
|
+
await (0, sleep_1.sleep)(20);
|
|
140
142
|
return objsAndPaths;
|
|
141
143
|
}, 1),
|
|
142
144
|
// check, emiting objId, if not synced, and undefined, if synced
|
|
143
|
-
operators_1.mergeMap(({ path, objId }) => this.sync(objId, async () => {
|
|
145
|
+
(0, operators_1.mergeMap)(({ path, objId }) => this.sync(objId, async () => {
|
|
144
146
|
if (this.objs.has(objId)) {
|
|
145
147
|
return;
|
|
146
148
|
}
|
|
147
149
|
const notSynced = await obj_status_1.ObjStatus.fileShowsObjNotInSyncedState(path, objId)
|
|
148
150
|
.catch(notFoundOrReThrow).catch(this.logError);
|
|
149
151
|
return (notSynced ? objId : undefined);
|
|
150
|
-
})), operators_1.filter(objId => (objId !== undefined)));
|
|
152
|
+
})), (0, operators_1.filter)(objId => (objId !== undefined)));
|
|
153
|
+
}
|
|
154
|
+
scheduleGC(obj) {
|
|
155
|
+
this.gc.scheduleCollection(obj);
|
|
151
156
|
}
|
|
152
157
|
}
|
|
153
158
|
exports.ObjFiles = ObjFiles;
|
|
@@ -155,10 +160,10 @@ Object.freeze(ObjFiles.prototype);
|
|
|
155
160
|
Object.freeze(ObjFiles);
|
|
156
161
|
function makeSynchronizer(proc) {
|
|
157
162
|
if (!proc) {
|
|
158
|
-
proc = new
|
|
163
|
+
proc = new synced_1.NamedProcs();
|
|
159
164
|
}
|
|
160
165
|
async function sync(objId, action) {
|
|
161
|
-
const id = (
|
|
166
|
+
const id = (objId ? objId : '==root==');
|
|
162
167
|
return proc.startOrChain(id, action);
|
|
163
168
|
}
|
|
164
169
|
return sync;
|
|
@@ -180,47 +185,26 @@ class SyncedObj {
|
|
|
180
185
|
this.status = status;
|
|
181
186
|
this.downloader = downloader;
|
|
182
187
|
this.scheduleGC = scheduleGC;
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
* These are conflicting versions, coming from a server. Of course, universal
|
|
190
|
-
* truth is spread by server, but in situations of parallel changes, local
|
|
191
|
-
* version allows things to work, while conflicting version from server
|
|
192
|
-
* should be adopted by conflict resolution process. In other words, these
|
|
193
|
-
* versions are not for common use.
|
|
194
|
-
*/
|
|
195
|
-
this.remoteConflictVerObjs = timed_cache_1.makeTimedCache(60 * 1000);
|
|
196
|
-
this.objSegsGetterFromDisk = async (ver, ofs, len) => {
|
|
197
|
-
let obj = this.verObjs.get(ver);
|
|
198
|
-
if (!obj) {
|
|
199
|
-
const fPath = this.path(ver, this.status.isVersionSynced(ver));
|
|
200
|
-
try {
|
|
201
|
-
obj = await obj_on_disk_1.ObjOnDisk.forExistingFile(this.objId, ver, fPath, this.downloader, this.objSegsGetterFromDisk);
|
|
202
|
-
this.verObjs.set(ver, obj);
|
|
203
|
-
}
|
|
204
|
-
catch (exc) {
|
|
205
|
-
// when file doesn't exist on a disk, we just pass a chunk
|
|
206
|
-
if (!exc.notFound) {
|
|
207
|
-
throw exc;
|
|
208
|
-
}
|
|
209
|
-
return [{ type: 'new', thisVerOfs: ofs, len }];
|
|
210
|
-
}
|
|
188
|
+
this.remoteVers = (0, timed_cache_1.makeTimedCache)(60 * 1000);
|
|
189
|
+
this.localVers = (0, timed_cache_1.makeTimedCache)(60 * 1000);
|
|
190
|
+
this.localAndSyncedObjSegsGetterFromDisk = async (v, ofs, len) => {
|
|
191
|
+
const latestSynced = this.status.latestSyncedVersion();
|
|
192
|
+
if (latestSynced && (latestSynced >= v)) {
|
|
193
|
+
return this.remoteObjSegsGetterFromDisk(v, ofs, len);
|
|
211
194
|
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
return this.objSegsGetterFromDisk(version, ofs, len);
|
|
195
|
+
let objVer = this.localVers.get(v);
|
|
196
|
+
if (!objVer) {
|
|
197
|
+
objVer = await obj_on_disk_1.ObjOnDisk.forExistingFile(this.objId, v, this.localVerPath(v), this.downloader, this.localAndSyncedObjSegsGetterFromDisk);
|
|
198
|
+
this.localVers.set(v, objVer);
|
|
217
199
|
}
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
200
|
+
return objVer.readSegsOnlyFromDisk(ofs, len);
|
|
201
|
+
};
|
|
202
|
+
this.remoteObjSegsGetterFromDisk = async (v, ofs, len) => {
|
|
203
|
+
let objVer = this.remoteVers.get(v);
|
|
204
|
+
if (!objVer) {
|
|
221
205
|
try {
|
|
222
|
-
|
|
223
|
-
this.
|
|
206
|
+
objVer = await obj_on_disk_1.ObjOnDisk.forExistingFile(this.objId, v, this.remoteVerPath(v), this.downloader, this.remoteObjSegsGetterFromDisk);
|
|
207
|
+
this.remoteVers.set(v, objVer);
|
|
224
208
|
}
|
|
225
209
|
catch (exc) {
|
|
226
210
|
// when file doesn't exist on a disk, we just pass a chunk
|
|
@@ -230,109 +214,178 @@ class SyncedObj {
|
|
|
230
214
|
return [{ type: 'new', thisVerOfs: ofs, len }];
|
|
231
215
|
}
|
|
232
216
|
}
|
|
233
|
-
return
|
|
217
|
+
return objVer.readSegsOnlyFromDisk(ofs, len);
|
|
234
218
|
};
|
|
235
219
|
Object.freeze(this);
|
|
236
220
|
}
|
|
237
|
-
static async forExistingObj(objId, objFolder, downloader, scheduleGC) {
|
|
238
|
-
const status = await obj_status_1.ObjStatus.readFrom(objFolder, objId);
|
|
221
|
+
static async forExistingObj(objId, objFolder, downloader, scheduleGC, logError) {
|
|
222
|
+
const status = await obj_status_1.ObjStatus.readFrom(objFolder, objId, logError);
|
|
239
223
|
return new SyncedObj(objId, objFolder, status, downloader, scheduleGC);
|
|
240
224
|
}
|
|
241
|
-
static async forDownloadedObj(objId, objFolder, downloader, scheduleGC, version, parts) {
|
|
242
|
-
|
|
225
|
+
static async forDownloadedObj(objId, objFolder, downloader, scheduleGC, version, parts, logError) {
|
|
226
|
+
// XXX let's note that given version is also passed as current on server
|
|
227
|
+
const status = await obj_status_1.ObjStatus.makeForDownloadedVersion(objFolder, objId, version, version, logError);
|
|
243
228
|
const obj = new SyncedObj(objId, objFolder, status, downloader, scheduleGC);
|
|
244
|
-
const fPath = obj.
|
|
245
|
-
const objVer = await obj_on_disk_1.ObjOnDisk.createFileForExistingVersion(obj.objId, version, fPath, obj.downloader, obj.
|
|
246
|
-
obj.
|
|
229
|
+
const fPath = obj.remoteVerPath(version);
|
|
230
|
+
const objVer = await obj_on_disk_1.ObjOnDisk.createFileForExistingVersion(obj.objId, version, fPath, obj.downloader, obj.remoteObjSegsGetterFromDisk, parts);
|
|
231
|
+
obj.remoteVers.set(version, objVer);
|
|
247
232
|
return obj;
|
|
248
233
|
}
|
|
249
|
-
static async forNewObj(objId, objFolder, downloader, scheduleGC) {
|
|
250
|
-
const status = await obj_status_1.ObjStatus.makeNew(objFolder, objId);
|
|
234
|
+
static async forNewObj(objId, objFolder, downloader, scheduleGC, logError) {
|
|
235
|
+
const status = await obj_status_1.ObjStatus.makeNew(objFolder, objId, logError);
|
|
251
236
|
return new SyncedObj(objId, objFolder, status, downloader, scheduleGC);
|
|
252
237
|
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
238
|
+
scheduleSelfGC() {
|
|
239
|
+
this.scheduleGC(this);
|
|
240
|
+
}
|
|
241
|
+
localVerPath(version) {
|
|
242
|
+
return (0, path_1.join)(this.objFolder, `${version}.${exports.UNSYNCED_FILE_NAME_EXT}`);
|
|
243
|
+
}
|
|
244
|
+
remoteVerPath(version) {
|
|
245
|
+
return (0, path_1.join)(this.objFolder, `${version}.${exports.REMOTE_FILE_NAME_EXT}`);
|
|
246
|
+
}
|
|
247
|
+
async getObjSrcFromLocalAndSyncedBranch(version) {
|
|
248
|
+
const latestSynced = this.status.latestSyncedVersion();
|
|
249
|
+
const objVer = await ((latestSynced && (latestSynced >= version)) ?
|
|
250
|
+
this.instanceOfRemoteObjVer(version) :
|
|
251
|
+
this.instanceOfLocalObjVer(version));
|
|
252
|
+
return objVer.getSrc();
|
|
257
253
|
}
|
|
258
|
-
async
|
|
259
|
-
|
|
254
|
+
async getObjSrcFromRemoteAndSyncedBranch(version) {
|
|
255
|
+
const objVer = await this.instanceOfRemoteObjVer(version);
|
|
256
|
+
return objVer.getSrc();
|
|
257
|
+
}
|
|
258
|
+
async instanceOfLocalObjVer(version) {
|
|
259
|
+
let objVer = this.localVers.get(version);
|
|
260
260
|
if (objVer) {
|
|
261
|
-
return objVer
|
|
262
|
-
}
|
|
263
|
-
const isSynced = this.status.isVersionSynced(version);
|
|
264
|
-
const fPath = this.path(version, isSynced);
|
|
265
|
-
if (isSynced) {
|
|
266
|
-
objVer = ((await isOnDisk(fPath)) ?
|
|
267
|
-
await obj_on_disk_1.ObjOnDisk.forExistingFile(this.objId, version, fPath, this.downloader, this.objSegsGetterFromDisk) :
|
|
268
|
-
await obj_on_disk_1.ObjOnDisk.createFileForExistingVersion(this.objId, version, fPath, this.downloader, this.objSegsGetterFromDisk));
|
|
261
|
+
return objVer;
|
|
269
262
|
}
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
this.verObjs.set(version, objVer);
|
|
275
|
-
return src;
|
|
263
|
+
const fPath = this.localVerPath(version);
|
|
264
|
+
objVer = await obj_on_disk_1.ObjOnDisk.forExistingFile(this.objId, version, fPath, this.downloader, this.localAndSyncedObjSegsGetterFromDisk);
|
|
265
|
+
this.localVers.set(version, objVer);
|
|
266
|
+
return objVer;
|
|
276
267
|
}
|
|
277
|
-
async
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
let obj = this.remoteConflictVerObjs.get(version);
|
|
282
|
-
if (obj) {
|
|
283
|
-
return obj.getSrc();
|
|
268
|
+
async instanceOfRemoteObjVer(version) {
|
|
269
|
+
let objVer = this.remoteVers.get(version);
|
|
270
|
+
if (objVer) {
|
|
271
|
+
return objVer;
|
|
284
272
|
}
|
|
285
|
-
const fPath = this.
|
|
286
|
-
|
|
287
|
-
await obj_on_disk_1.ObjOnDisk.forExistingFile(this.objId, version, fPath, this.downloader, this.
|
|
288
|
-
await obj_on_disk_1.ObjOnDisk.createFileForExistingVersion(this.objId, version, fPath, this.downloader, this.
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
return src;
|
|
273
|
+
const fPath = this.remoteVerPath(version);
|
|
274
|
+
objVer = ((await isOnDisk(fPath)) ?
|
|
275
|
+
await obj_on_disk_1.ObjOnDisk.forExistingFile(this.objId, version, fPath, this.downloader, this.remoteObjSegsGetterFromDisk) :
|
|
276
|
+
await obj_on_disk_1.ObjOnDisk.createFileForExistingVersion(this.objId, version, fPath, this.downloader, this.remoteObjSegsGetterFromDisk));
|
|
277
|
+
this.remoteVers.set(version, objVer);
|
|
278
|
+
return objVer;
|
|
292
279
|
}
|
|
293
280
|
async saveNewVersion(version, encSub) {
|
|
294
|
-
if (this.
|
|
281
|
+
if (this.localVers.has(version)) {
|
|
295
282
|
throw new Error(`Version ${version} already exists in object ${this.objId}`);
|
|
296
283
|
}
|
|
297
|
-
const fPath = this.
|
|
298
|
-
const { obj, write$ } = await obj_on_disk_1.ObjOnDisk.createFileForWriteOfNewVersion(this.objId, version, fPath, encSub, this.downloader, this.
|
|
299
|
-
this.
|
|
300
|
-
const fileWrite$ = write$.pipe(operators_1.tap(
|
|
301
|
-
|
|
302
|
-
this.
|
|
284
|
+
const fPath = this.localVerPath(version);
|
|
285
|
+
const { obj, write$ } = await obj_on_disk_1.ObjOnDisk.createFileForWriteOfNewVersion(this.objId, version, fPath, encSub, this.downloader, this.localAndSyncedObjSegsGetterFromDisk);
|
|
286
|
+
this.localVers.set(version, obj);
|
|
287
|
+
const fileWrite$ = write$.pipe((0, operators_1.tap)({
|
|
288
|
+
error: err => {
|
|
289
|
+
if (this.localVers.get(version) === obj) {
|
|
290
|
+
this.localVers.delete(version);
|
|
291
|
+
}
|
|
303
292
|
}
|
|
304
|
-
}), utils_for_observables_1.flatTap(undefined, undefined, () => this.setUnsyncedCurrentVersion(version)));
|
|
293
|
+
}), (0, utils_for_observables_1.flatTap)(undefined, undefined, () => this.setUnsyncedCurrentVersion(version, obj.getBaseVersion())));
|
|
305
294
|
return { fileWrite$, baseVer: obj.getBaseVersion() };
|
|
306
295
|
}
|
|
307
|
-
|
|
308
|
-
|
|
296
|
+
async combineLocalBaseIfPresent(version) {
|
|
297
|
+
const bases = this.status.baseOfLocalVersion(version);
|
|
298
|
+
if (!bases) {
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
const { localBases, syncedBase } = bases;
|
|
302
|
+
if (localBases) {
|
|
303
|
+
const objVer = await this.instanceOfLocalObjVer(version);
|
|
304
|
+
for (const localBase of localBases) {
|
|
305
|
+
await objVer.absorbImmediateBaseVersion(localBase, this.localVerPath(localBase));
|
|
306
|
+
this.status.absorbLocalVersionBase(version, localBase);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
return syncedBase;
|
|
309
310
|
}
|
|
310
|
-
|
|
311
|
-
|
|
311
|
+
async saveUploadHeaderFile(uploadHeader) {
|
|
312
|
+
await (0, upload_header_file_1.saveUploadHeaderFile)(this.objFolder, uploadHeader);
|
|
312
313
|
}
|
|
313
|
-
|
|
314
|
-
|
|
314
|
+
async setUnsyncedCurrentVersion(version, baseVersion) {
|
|
315
|
+
await this.status.setLocalCurrentVersion(version, baseVersion);
|
|
316
|
+
if (version > 1) {
|
|
317
|
+
this.scheduleSelfGC();
|
|
318
|
+
}
|
|
315
319
|
}
|
|
316
|
-
|
|
317
|
-
|
|
320
|
+
/**
|
|
321
|
+
* This renames/moves version file from local to remote.
|
|
322
|
+
* Removes upload info from status, updating enumerations of local and
|
|
323
|
+
* synced versions.
|
|
324
|
+
*/
|
|
325
|
+
async recordUploadCompletion(localVersion, uploadVersion, headerChange) {
|
|
326
|
+
const verObj = this.localVers.get(localVersion);
|
|
327
|
+
const remotePath = this.remoteVerPath(uploadVersion);
|
|
328
|
+
if (verObj) {
|
|
329
|
+
const syncedVerObj = await verObj.moveFileAndProxyThis(remotePath, (headerChange ? {
|
|
330
|
+
newHeader: headerChange.newHeader,
|
|
331
|
+
originalHeader: headerChange.originalHeader,
|
|
332
|
+
version: uploadVersion
|
|
333
|
+
} : undefined));
|
|
334
|
+
this.remoteVers.set(uploadVersion, syncedVerObj);
|
|
335
|
+
}
|
|
336
|
+
else {
|
|
337
|
+
await fs.rename(this.localVerPath(localVersion), remotePath);
|
|
338
|
+
}
|
|
339
|
+
await this.status.markLocalVersionSynced(localVersion, uploadVersion);
|
|
340
|
+
this.scheduleSelfGC();
|
|
318
341
|
}
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
342
|
+
dropCachedLocalObjVersionsLessOrEqual(version) {
|
|
343
|
+
for (const version of this.localVers.keys()) {
|
|
344
|
+
if (version <= version) {
|
|
345
|
+
this.localVers.delete(version);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
322
348
|
}
|
|
323
|
-
async
|
|
324
|
-
await this.
|
|
325
|
-
|
|
349
|
+
async removeLocalVersionFilesLessThan(version) {
|
|
350
|
+
const lst = await fs.readdir(this.objFolder).catch(utils_1.noop);
|
|
351
|
+
if (!lst) {
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
const rmProcs = [];
|
|
355
|
+
for (const f of lst) {
|
|
356
|
+
if (!f.endsWith(exports.UNSYNCED_FILE_NAME_EXT)) {
|
|
357
|
+
continue;
|
|
358
|
+
}
|
|
359
|
+
const verStr = f.slice(0, f.length - 1 - exports.UNSYNCED_FILE_NAME_EXT.length);
|
|
360
|
+
const ver = parseInt(verStr);
|
|
361
|
+
if (isNaN(ver) || (ver > version)) {
|
|
362
|
+
continue;
|
|
363
|
+
}
|
|
364
|
+
rmProcs.push(fs.unlink((0, path_1.join)(this.objFolder, f)).catch(utils_1.noop));
|
|
365
|
+
}
|
|
366
|
+
if (rmProcs.length > 0) {
|
|
367
|
+
await Promise.all(rmProcs);
|
|
368
|
+
}
|
|
326
369
|
}
|
|
327
|
-
async
|
|
328
|
-
await this.status.
|
|
370
|
+
async removeCurrentVersion() {
|
|
371
|
+
await this.status.removeCurrentVersion();
|
|
372
|
+
// note that gc is tasked with removing current obj version on server
|
|
373
|
+
this.scheduleSelfGC();
|
|
329
374
|
}
|
|
330
|
-
async
|
|
331
|
-
await this.
|
|
375
|
+
async diffForUploadOf(version) {
|
|
376
|
+
const objVer = await this.instanceOfLocalObjVer(version);
|
|
377
|
+
if (objVer.getBaseVersion()) {
|
|
378
|
+
return objVer.diffFromBase();
|
|
379
|
+
}
|
|
380
|
+
else {
|
|
381
|
+
throw new Error(`Version ${version} is not a diff version`);
|
|
382
|
+
}
|
|
332
383
|
}
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
384
|
+
syncStatus() {
|
|
385
|
+
return this.status;
|
|
386
|
+
}
|
|
387
|
+
statusObj() {
|
|
388
|
+
return this.status;
|
|
336
389
|
}
|
|
337
390
|
}
|
|
338
391
|
exports.SyncedObj = SyncedObj;
|