core-3nweb-client-lib 0.26.1 → 0.27.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/api-defs/asmail.d.ts +1 -1
- package/build/api-defs/files.d.ts +281 -75
- package/build/core/app-files.js +7 -7
- package/build/core/asmail/config/common.js +2 -2
- package/build/core/asmail/config/index.js +2 -2
- package/build/core/asmail/config/published-intro-key.js +1 -1
- package/build/core/asmail/delivery/common.js +7 -7
- package/build/core/asmail/delivery/index.js +5 -5
- package/build/core/asmail/delivery/msg.js +4 -4
- package/build/core/asmail/delivery/per-recipient-wip.js +1 -1
- package/build/core/asmail/inbox/attachments/fs.d.ts +2 -1
- package/build/core/asmail/inbox/attachments/fs.js +9 -4
- package/build/core/asmail/inbox/cached-msgs.js +1 -1
- package/build/core/asmail/inbox/inbox-events.js +4 -4
- package/build/core/asmail/inbox/index.js +10 -10
- package/build/core/asmail/inbox/msg-downloader.js +1 -1
- package/build/core/asmail/inbox/msg-indexing.js +1 -1
- package/build/core/asmail/inbox/msg-on-disk.js +5 -5
- package/build/core/asmail/index.d.ts +3 -3
- package/build/core/asmail/index.js +13 -8
- package/build/core/asmail/key-verification.js +5 -5
- package/build/core/asmail/keyring/common.js +7 -6
- package/build/core/asmail/keyring/correspondent-keys.js +8 -7
- package/build/core/asmail/keyring/id-to-email-map.js +2 -1
- package/build/core/asmail/keyring/index.d.ts +7 -8
- package/build/core/asmail/keyring/index.js +15 -14
- package/build/core/asmail/keyring/keyring-storage.js +2 -1
- package/build/core/asmail/msg/opener.js +3 -3
- package/build/core/asmail/msg/packer.js +13 -13
- package/build/core/asmail/sending-params/own-params.js +2 -2
- package/build/core/asmail/sending-params/params-from-others.js +1 -1
- package/build/core/id-manager/index.d.ts +43 -0
- package/build/core/{id-manager.js → id-manager/index.js} +36 -114
- package/build/core/id-manager/key-storage.d.ts +21 -0
- package/build/core/id-manager/key-storage.js +96 -0
- package/build/core/index.d.ts +2 -1
- package/build/core/index.js +31 -33
- package/build/core/sign-in.d.ts +1 -2
- package/build/core/sign-in.js +8 -17
- package/build/core/sign-up.d.ts +2 -0
- package/build/core/sign-up.js +11 -10
- package/build/core/storage/common/json-saving.js +2 -2
- package/build/core/storage/common/obj-info-file.d.ts +12 -4
- package/build/core/storage/common/obj-info-file.js +66 -34
- package/build/core/storage/common/utils.d.ts +2 -0
- package/build/core/storage/common/utils.js +32 -0
- package/build/core/storage/index.d.ts +5 -17
- package/build/core/storage/index.js +78 -119
- package/build/core/storage/local/obj-files-gc.d.ts +2 -0
- package/build/core/storage/local/obj-files-gc.js +49 -37
- package/build/core/storage/local/obj-files.d.ts +4 -7
- package/build/core/storage/local/obj-files.js +7 -10
- package/build/core/storage/local/obj-status.d.ts +12 -6
- package/build/core/storage/local/obj-status.js +24 -9
- package/build/core/storage/local/storage.d.ts +10 -7
- package/build/core/storage/local/storage.js +29 -18
- package/build/core/storage/synced/downloader.js +1 -1
- package/build/core/storage/synced/obj-files-gc.d.ts +1 -0
- package/build/core/storage/synced/obj-files-gc.js +76 -39
- package/build/core/storage/synced/obj-files.d.ts +50 -36
- package/build/core/storage/synced/obj-files.js +201 -162
- package/build/core/storage/synced/obj-status.d.ts +99 -86
- package/build/core/storage/synced/obj-status.js +520 -251
- package/build/core/storage/synced/remote-events.d.ts +11 -12
- package/build/core/storage/synced/remote-events.js +73 -56
- package/build/core/storage/synced/storage.d.ts +24 -10
- package/build/core/storage/synced/storage.js +147 -47
- package/build/core/storage/synced/upload-header-file.d.ts +4 -0
- package/build/core/storage/synced/upload-header-file.js +64 -0
- package/build/core/storage/synced/upsyncer.d.ts +12 -7
- package/build/core/storage/synced/upsyncer.js +210 -280
- package/build/core/storage/system-folders/apps-data.d.ts +16 -0
- package/build/core/storage/system-folders/apps-data.js +110 -0
- package/build/core/storage/system-folders/index.d.ts +18 -0
- package/build/core/storage/system-folders/index.js +77 -0
- package/build/core-ipc/common-caps.js +3 -3
- package/build/core-ipc/generic.js +8 -8
- package/build/core-ipc/startup-caps.js +2 -2
- package/build/cryptors.js +6 -2
- package/build/ipc-via-protobuf/asmail-cap.js +58 -57
- package/build/ipc-via-protobuf/bytes.js +16 -17
- package/build/ipc-via-protobuf/connector-clients-side.d.ts +1 -0
- package/build/ipc-via-protobuf/connector-clients-side.js +14 -15
- package/build/ipc-via-protobuf/connector-services-side.js +10 -10
- package/build/ipc-via-protobuf/connector.js +4 -4
- package/build/ipc-via-protobuf/file.d.ts +48 -12
- package/build/ipc-via-protobuf/file.js +474 -126
- package/build/ipc-via-protobuf/fs.d.ts +8 -0
- package/build/ipc-via-protobuf/fs.js +577 -142
- package/build/ipc-via-protobuf/log-cap.js +2 -2
- package/build/ipc-via-protobuf/mailerid.js +3 -3
- package/build/ipc-via-protobuf/protobuf-msg.d.ts +1 -0
- package/build/ipc-via-protobuf/protobuf-msg.js +11 -7
- package/build/ipc-via-protobuf/startup-cap.js +21 -21
- package/build/ipc-via-protobuf/storage-cap.js +12 -12
- package/build/ipc.js +7 -2
- package/build/lib-client/3nstorage/exceptions.d.ts +16 -1
- package/build/lib-client/3nstorage/exceptions.js +21 -3
- package/build/lib-client/3nstorage/service.d.ts +21 -3
- package/build/lib-client/3nstorage/service.js +128 -46
- package/build/lib-client/3nstorage/util/file-based-json.d.ts +2 -1
- package/build/lib-client/3nstorage/util/file-based-json.js +3 -2
- package/build/lib-client/3nstorage/util/for-arrays.d.ts +1 -0
- package/build/lib-client/3nstorage/util/for-arrays.js +32 -0
- package/build/lib-client/3nstorage/xsp-fs/attrs.js +17 -17
- package/build/lib-client/3nstorage/xsp-fs/common.d.ts +44 -19
- package/build/lib-client/3nstorage/xsp-fs/common.js +30 -19
- package/build/lib-client/3nstorage/xsp-fs/file-node.d.ts +1 -0
- package/build/lib-client/3nstorage/xsp-fs/file-node.js +17 -13
- package/build/lib-client/3nstorage/xsp-fs/file.d.ts +31 -6
- package/build/lib-client/3nstorage/xsp-fs/file.js +73 -25
- package/build/lib-client/3nstorage/xsp-fs/folder-node-serialization.js +4 -4
- package/build/lib-client/3nstorage/xsp-fs/folder-node.d.ts +32 -13
- package/build/lib-client/3nstorage/xsp-fs/folder-node.js +752 -192
- package/build/lib-client/3nstorage/xsp-fs/fs.d.ts +35 -4
- package/build/lib-client/3nstorage/xsp-fs/fs.js +236 -119
- package/build/lib-client/3nstorage/xsp-fs/link-node.d.ts +1 -0
- package/build/lib-client/3nstorage/xsp-fs/link-node.js +7 -2
- package/build/lib-client/3nstorage/xsp-fs/node-in-fs.d.ts +30 -29
- package/build/lib-client/3nstorage/xsp-fs/node-in-fs.js +232 -127
- package/build/lib-client/3nstorage/xsp-fs/node-persistence.d.ts +1 -1
- package/build/lib-client/3nstorage/xsp-fs/node-persistence.js +17 -18
- package/build/lib-client/3nstorage/xsp-fs/xsp-payload-v1.js +3 -3
- package/build/lib-client/3nstorage/xsp-fs/xsp-payload-v2.js +53 -53
- package/build/lib-client/3nweb-signup.js +4 -4
- package/build/lib-client/asmail/recipient.js +15 -15
- package/build/lib-client/asmail/sender.js +22 -22
- package/build/lib-client/asmail/service-config.js +3 -3
- package/build/lib-client/cryptor/cryptor-in-worker.js +18 -16
- package/build/lib-client/cryptor/cryptor-wasm.js +1 -1
- package/build/lib-client/cryptor/cryptor.js +4 -2
- package/build/lib-client/cryptor/cryptor.wasm +0 -0
- package/build/lib-client/cryptor/in-proc-js.js +1 -1
- package/build/lib-client/cryptor/in-proc-wasm.js +6 -6
- package/build/lib-client/cryptor/worker-js.js +2 -2
- package/build/lib-client/cryptor/worker-wasm.js +2 -2
- package/build/lib-client/files-select.js +1 -1
- package/build/lib-client/files.d.ts +1 -1
- package/build/lib-client/files.js +71 -6
- package/build/lib-client/fs-collection.js +1 -1
- package/build/lib-client/fs-sync-utils.d.ts +5 -0
- package/build/lib-client/fs-sync-utils.js +61 -0
- package/build/lib-client/fs-view.d.ts +14 -0
- package/build/lib-client/fs-view.js +33 -0
- package/build/lib-client/key-derivation.js +1 -1
- package/build/lib-client/local-files/dev-file-sink.js +9 -9
- package/build/lib-client/local-files/dev-file-src.js +2 -2
- package/build/lib-client/local-files/device-fs.d.ts +1 -1
- package/build/lib-client/local-files/device-fs.js +56 -54
- package/build/lib-client/logging/log-to-file.d.ts +1 -1
- package/build/lib-client/logging/log-to-file.js +7 -7
- package/build/lib-client/mailer-id/login.js +7 -7
- package/build/lib-client/mailer-id/provisioner.js +12 -12
- package/build/lib-client/objs-on-disk/file-writing-proc.js +3 -3
- package/build/lib-client/objs-on-disk/obj-folders.js +31 -31
- package/build/lib-client/objs-on-disk/obj-on-disk.d.ts +13 -2
- package/build/lib-client/objs-on-disk/obj-on-disk.js +24 -9
- package/build/lib-client/request-utils.d.ts +1 -0
- package/build/lib-client/request-utils.js +13 -13
- package/build/lib-client/server-events.d.ts +3 -3
- package/build/lib-client/server-events.js +9 -8
- package/build/lib-client/service-locator.js +10 -10
- package/build/lib-client/user-with-mid-session.d.ts +2 -1
- package/build/lib-client/user-with-mid-session.js +14 -8
- package/build/lib-client/user-with-pkl-session.js +25 -25
- package/build/lib-client/ws-utils.js +2 -2
- package/build/lib-common/async-cryptor-wrap.js +4 -4
- package/build/lib-common/async-fs-node.d.ts +5 -3
- package/build/lib-common/async-fs-node.js +17 -17
- package/build/lib-common/byte-streaming/pipe.js +1 -1
- package/build/lib-common/byte-streaming/wrapping.js +13 -13
- package/build/lib-common/canonical-address.js +1 -1
- package/build/lib-common/exceptions/error.d.ts +1 -0
- package/build/lib-common/exceptions/error.js +7 -6
- package/build/lib-common/exceptions/file.d.ts +4 -2
- package/build/lib-common/exceptions/file.js +24 -54
- package/build/lib-common/ipc/generic-ipc.js +5 -4
- package/build/lib-common/ipc/ws-ipc.js +2 -2
- package/build/lib-common/mid-sigs-NaCl-Ed.js +14 -14
- package/build/lib-common/objs-on-disk/file-layout.d.ts +19 -0
- package/build/lib-common/objs-on-disk/file-layout.js +130 -12
- package/build/lib-common/objs-on-disk/obj-file.d.ts +13 -2
- package/build/lib-common/objs-on-disk/obj-file.js +96 -35
- package/build/lib-common/objs-on-disk/utils.d.ts +1 -0
- package/build/lib-common/objs-on-disk/utils.js +3 -3
- package/build/lib-common/objs-on-disk/v1-obj-file-format.js +14 -14
- package/build/lib-common/processes/labelled-exec-pools.d.ts +1 -1
- package/build/lib-common/processes/labelled-exec-pools.js +1 -1
- package/build/lib-common/processes/pressure.js +2 -2
- package/build/lib-common/processes/synced.js +1 -1
- package/build/lib-common/processes/timeout.js +2 -2
- package/build/lib-common/random-node.js +7 -7
- package/build/lib-common/service-api/3nstorage/owner.d.ts +101 -42
- package/build/lib-common/service-api/3nstorage/owner.js +83 -40
- package/build/lib-common/service-api/asmail/delivery.js +2 -2
- package/build/lib-common/service-api/asmail/retrieval.js +1 -1
- package/build/lib-common/timed-cache.d.ts +1 -0
- package/build/lib-common/timed-non-weak-cache.d.ts +1 -0
- package/build/lib-common/timed-non-weak-cache.js +11 -0
- package/build/lib-common/utils-for-observables.js +4 -4
- package/build/lib-common/weak-cache.d.ts +1 -0
- package/build/lib-common/weak-cache.js +12 -1
- package/build/lib-index.d.ts +2 -1
- package/build/lib-index.js +10 -7
- package/build/protos/asmail.proto.js +12955 -7496
- package/build/protos/file.proto.js +4867 -2744
- package/build/protos/fs.proto.js +9227 -3768
- package/package.json +7 -5
- package/protos/file.proto +91 -19
- package/protos/fs.proto +107 -8
- package/build/core/id-manager.d.ts +0 -46
|
@@ -1,23 +1,22 @@
|
|
|
1
1
|
import { StorageOwner } from '../../../lib-client/3nstorage/service';
|
|
2
2
|
import { ObjFiles } from './obj-files';
|
|
3
|
-
import {
|
|
3
|
+
import { Storage } from '../../../lib-client/3nstorage/xsp-fs/common';
|
|
4
4
|
import { LogError } from '../../../lib-client/logging/log-to-file';
|
|
5
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Remote events are absorbed into objects' statuses, broadcasting respective
|
|
7
|
+
* events. Someone down the stream can react to these changes from remote.
|
|
8
|
+
*/
|
|
6
9
|
export declare class RemoteEvents {
|
|
7
10
|
private readonly remoteStorage;
|
|
8
11
|
private readonly files;
|
|
9
|
-
private readonly
|
|
12
|
+
private readonly broadcastNodeEvent;
|
|
10
13
|
private readonly logError;
|
|
11
|
-
constructor(remoteStorage: StorageOwner, files: ObjFiles,
|
|
14
|
+
constructor(remoteStorage: StorageOwner, files: ObjFiles, broadcastNodeEvent: Storage['broadcastNodeEvent'], logError: LogError);
|
|
12
15
|
private absorbingRemoteEventsProc;
|
|
13
16
|
startAbsorbingRemoteEvents(): void;
|
|
14
17
|
close(): Promise<void>;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
* @param objChange
|
|
20
|
-
*/
|
|
21
|
-
private remoteChange;
|
|
22
|
-
private remoteRemoval;
|
|
18
|
+
private absorbObjChange;
|
|
19
|
+
private absorbObjRemoval;
|
|
20
|
+
private absorbObjVersionArchival;
|
|
21
|
+
private absorbArchVersionRemoval;
|
|
23
22
|
}
|
|
@@ -22,83 +22,100 @@ const server_events_1 = require("../../../lib-client/server-events");
|
|
|
22
22
|
const owner_1 = require("../../../lib-common/service-api/3nstorage/owner");
|
|
23
23
|
const operators_1 = require("rxjs/operators");
|
|
24
24
|
const SERVER_EVENTS_RESTART_WAIT_SECS = 30;
|
|
25
|
+
/**
|
|
26
|
+
* Remote events are absorbed into objects' statuses, broadcasting respective
|
|
27
|
+
* events. Someone down the stream can react to these changes from remote.
|
|
28
|
+
*/
|
|
25
29
|
class RemoteEvents {
|
|
26
|
-
constructor(remoteStorage, files,
|
|
30
|
+
constructor(remoteStorage, files, broadcastNodeEvent, logError) {
|
|
27
31
|
this.remoteStorage = remoteStorage;
|
|
28
32
|
this.files = files;
|
|
29
|
-
this.
|
|
33
|
+
this.broadcastNodeEvent = broadcastNodeEvent;
|
|
30
34
|
this.logError = logError;
|
|
31
35
|
this.absorbingRemoteEventsProc = undefined;
|
|
32
36
|
Object.seal(this);
|
|
33
37
|
}
|
|
34
38
|
startAbsorbingRemoteEvents() {
|
|
35
39
|
const serverEvents = new server_events_1.ServerEvents(() => this.remoteStorage.openEventSource(), SERVER_EVENTS_RESTART_WAIT_SECS);
|
|
36
|
-
|
|
37
|
-
.pipe(operators_1.filter(objChange => Number.isInteger(objChange.newVer) && (objChange.newVer > 1)), operators_1.mergeMap(objChange => this.remoteChange(objChange)));
|
|
38
|
-
const objRemoval$ = serverEvents.observe(owner_1.objRemoved.EVENT_NAME)
|
|
39
|
-
.pipe(operators_1.filter(objRm => !!objRm.objId), operators_1.mergeMap(objRm => this.remoteRemoval(objRm)));
|
|
40
|
-
this.absorbingRemoteEventsProc = rxjs_1.merge(objChange$, objRemoval$)
|
|
40
|
+
this.absorbingRemoteEventsProc = (0, rxjs_1.merge)(this.absorbObjChange(serverEvents), this.absorbObjRemoval(serverEvents), this.absorbObjVersionArchival(serverEvents), this.absorbArchVersionRemoval(serverEvents))
|
|
41
41
|
.subscribe({
|
|
42
42
|
next: noop,
|
|
43
|
-
error: err =>
|
|
44
|
-
|
|
43
|
+
error: async (err) => {
|
|
44
|
+
await this.logError(err);
|
|
45
|
+
this.absorbingRemoteEventsProc = undefined;
|
|
46
|
+
},
|
|
47
|
+
complete: () => {
|
|
48
|
+
this.absorbingRemoteEventsProc = undefined;
|
|
49
|
+
}
|
|
45
50
|
});
|
|
46
51
|
}
|
|
47
52
|
async close() {
|
|
48
53
|
if (this.absorbingRemoteEventsProc) {
|
|
49
54
|
this.absorbingRemoteEventsProc.unsubscribe();
|
|
55
|
+
this.absorbingRemoteEventsProc = undefined;
|
|
50
56
|
}
|
|
51
57
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
*/
|
|
58
|
-
async remoteChange(objChange) {
|
|
59
|
-
const obj = await this.files.findObj(objChange.objId);
|
|
60
|
-
if (!obj) {
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
if (obj.isRemoteVersionGreaterOrEqualTo(objChange.newVer)) {
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
await obj.setRemoteVersion(objChange.newVer);
|
|
67
|
-
const nodeInFS = this.fsNodes(objChange.objId);
|
|
68
|
-
if (!nodeInFS) {
|
|
69
|
-
return;
|
|
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`);
|
|
58
|
+
absorbObjChange(serverEvents) {
|
|
59
|
+
return serverEvents.observe(owner_1.events.objChanged.EVENT_NAME)
|
|
60
|
+
.pipe((0, operators_1.mergeMap)(async ({ newVer, objId }) => {
|
|
61
|
+
if (!Number.isInteger(newVer) || (newVer < 1)) {
|
|
62
|
+
return;
|
|
78
63
|
}
|
|
79
|
-
|
|
64
|
+
const obj = await this.files.findObj(objId);
|
|
65
|
+
if (!obj) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
obj.statusObj().recordRemoteChange(newVer);
|
|
69
|
+
this.broadcastNodeEvent(obj.objId, undefined, undefined, {
|
|
70
|
+
type: 'remote-change',
|
|
71
|
+
path: '',
|
|
72
|
+
newVersion: newVer
|
|
73
|
+
});
|
|
74
|
+
}, 1));
|
|
80
75
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
await obj.setDeletedOnRemote();
|
|
90
|
-
const nodeInFS = this.fsNodes(objRm.objId);
|
|
91
|
-
if (!nodeInFS) {
|
|
92
|
-
return;
|
|
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`);
|
|
76
|
+
absorbObjRemoval(serverEvents) {
|
|
77
|
+
return serverEvents.observe(owner_1.events.objRemoved.EVENT_NAME)
|
|
78
|
+
.pipe((0, operators_1.filter)((objRm) => !!objRm.objId), (0, operators_1.mergeMap)(async ({ objId }) => {
|
|
79
|
+
const obj = await this.files.findObj(objId);
|
|
80
|
+
if (!obj) {
|
|
81
|
+
return;
|
|
100
82
|
}
|
|
101
|
-
|
|
83
|
+
obj.statusObj().recordRemoteRemoval();
|
|
84
|
+
this.broadcastNodeEvent(obj.objId, undefined, undefined, {
|
|
85
|
+
type: 'remote-removal',
|
|
86
|
+
path: ''
|
|
87
|
+
});
|
|
88
|
+
}, 1));
|
|
89
|
+
}
|
|
90
|
+
absorbObjVersionArchival(serverEvents) {
|
|
91
|
+
return serverEvents.observe(owner_1.events.objVersionArchived.EVENT_NAME)
|
|
92
|
+
.pipe((0, operators_1.mergeMap)(async ({ objId, archivedVer }) => {
|
|
93
|
+
const obj = await this.files.findObj(objId);
|
|
94
|
+
if (!obj) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
obj.statusObj().recordVersionArchival(archivedVer);
|
|
98
|
+
this.broadcastNodeEvent(obj.objId, undefined, undefined, {
|
|
99
|
+
type: 'remote-version-archival',
|
|
100
|
+
path: '',
|
|
101
|
+
archivedVersion: archivedVer
|
|
102
|
+
});
|
|
103
|
+
}, 1));
|
|
104
|
+
}
|
|
105
|
+
absorbArchVersionRemoval(serverEvents) {
|
|
106
|
+
return serverEvents.observe(owner_1.events.objArchivedVersionRemoved.EVENT_NAME)
|
|
107
|
+
.pipe((0, operators_1.mergeMap)(async ({ objId, archivedVer }) => {
|
|
108
|
+
const obj = await this.files.findObj(objId);
|
|
109
|
+
if (!obj) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
obj.statusObj().recordArchVersionRemoval(archivedVer);
|
|
113
|
+
this.broadcastNodeEvent(obj.objId, undefined, undefined, {
|
|
114
|
+
type: 'remote-arch-ver-removal',
|
|
115
|
+
path: '',
|
|
116
|
+
removedArchVer: archivedVer
|
|
117
|
+
});
|
|
118
|
+
}, 1));
|
|
102
119
|
}
|
|
103
120
|
}
|
|
104
121
|
exports.RemoteEvents = RemoteEvents;
|
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
import { IGetMailerIdSigner } from '../../../lib-client/user-with-mid-session';
|
|
2
|
-
import { SyncedStorage as ISyncedStorage, NodesContainer, Storage as IStorage, StorageGetter, ObjId, NodeEvent } from '../../../lib-client/3nstorage/xsp-fs/common';
|
|
2
|
+
import { SyncedStorage as ISyncedStorage, NodesContainer, Storage as IStorage, StorageGetter, ObjId, NodeEvent, SyncedObjStatus } 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
7
|
import { Observable } from 'rxjs';
|
|
8
|
+
import { UploadHeaderChange } from '../../../lib-client/3nstorage/xsp-fs/common';
|
|
8
9
|
declare type FolderEvent = web3n.files.FolderEvent;
|
|
9
10
|
declare type FileEvent = web3n.files.FileEvent;
|
|
10
|
-
declare type
|
|
11
|
+
declare type SyncStatus = web3n.files.SyncStatus;
|
|
12
|
+
declare type OptionsToAdopteRemote = web3n.files.OptionsToAdopteRemote;
|
|
11
13
|
export declare class SyncedStore implements ISyncedStorage {
|
|
12
14
|
private readonly files;
|
|
13
15
|
private readonly remoteStorage;
|
|
14
16
|
private readonly getStorages;
|
|
15
17
|
readonly cryptor: AsyncSBoxCryptor;
|
|
16
|
-
|
|
18
|
+
readonly logError: LogError;
|
|
17
19
|
readonly type: web3n.files.FSType;
|
|
18
20
|
readonly versioned = true;
|
|
19
21
|
readonly nodes: NodesContainer;
|
|
@@ -21,21 +23,33 @@ export declare class SyncedStore implements ISyncedStorage {
|
|
|
21
23
|
private readonly uploader;
|
|
22
24
|
private readonly events;
|
|
23
25
|
private constructor();
|
|
24
|
-
static makeAndStart(path: string, user: string, getSigner: IGetMailerIdSigner, getStorages: StorageGetter, cryptor: AsyncSBoxCryptor, remoteServiceUrl: () => Promise<string>,
|
|
26
|
+
static makeAndStart(path: string, user: string, getSigner: IGetMailerIdSigner, getStorages: StorageGetter, cryptor: AsyncSBoxCryptor, remoteServiceUrl: () => Promise<string>, net: NetClient, logError: LogError): Promise<{
|
|
25
27
|
syncedStore: ISyncedStorage;
|
|
26
28
|
startObjProcs: () => void;
|
|
27
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
|
+
}>;
|
|
28
34
|
getNodeEvents(): Observable<NodeEvent>;
|
|
29
|
-
broadcastNodeEvent(objId: ObjId, parentObjId: ObjId | undefined, event: FolderEvent | FileEvent): void;
|
|
30
|
-
private broadcastUpSyncEvent;
|
|
35
|
+
broadcastNodeEvent(objId: ObjId, parentObjId: ObjId | undefined, childObjId: ObjId | undefined, event: FolderEvent | FileEvent): void;
|
|
31
36
|
storageForLinking(type: web3n.files.FSType, location?: string): IStorage;
|
|
32
|
-
|
|
37
|
+
status(objId: ObjId): Promise<SyncedObjStatus>;
|
|
38
|
+
adoptRemote(objId: ObjId, opts: OptionsToAdopteRemote | undefined): Promise<number | undefined>;
|
|
39
|
+
updateStatusInfo(objId: ObjId): Promise<SyncStatus>;
|
|
40
|
+
isObjOnDisk(objId: ObjId): Promise<boolean>;
|
|
41
|
+
isRemoteVersionOnDisk(objId: ObjId, version: number): Promise<'complete' | 'partial' | 'none'>;
|
|
42
|
+
download(objId: ObjId, version: number): Promise<void>;
|
|
43
|
+
upload(objId: ObjId, localVersion: number, uploadVersion: number, uploadHeader: UploadHeaderChange | undefined, createOnRemote: boolean): Promise<void>;
|
|
44
|
+
uploadObjRemoval(objId: ObjId): Promise<void>;
|
|
45
|
+
dropCachedLocalObjVersionsLessOrEqual(objId: ObjId, version: number): void;
|
|
46
|
+
archiveVersionOnServer(objId: ObjId, version: number): Promise<void>;
|
|
33
47
|
getRootKeyDerivParamsFromServer(): Promise<ScryptGenParams>;
|
|
34
48
|
generateNewObjId(): Promise<string>;
|
|
35
49
|
private objFromDiskOrDownload;
|
|
36
|
-
private
|
|
37
|
-
|
|
38
|
-
|
|
50
|
+
private getObjOrThrow;
|
|
51
|
+
getObjSrc(objId: ObjId, version?: number, allowArchived?: boolean): Promise<ObjSource>;
|
|
52
|
+
getObjSrcOfRemoteVersion(objId: ObjId, version: number): Promise<ObjSource>;
|
|
39
53
|
saveObj(objId: ObjId, version: number, encSub: Subscribe): Promise<void>;
|
|
40
54
|
removeObj(objId: string): Promise<void>;
|
|
41
55
|
close(): Promise<void>;
|
|
@@ -24,7 +24,6 @@ const obj_files_1 = require("./obj-files");
|
|
|
24
24
|
const random_node_1 = require("../../../lib-common/random-node");
|
|
25
25
|
const buffer_utils_1 = require("../../../lib-common/buffer-utils");
|
|
26
26
|
const xsp_files_1 = require("xsp-files");
|
|
27
|
-
const downloader_1 = require("./downloader");
|
|
28
27
|
const remote_events_1 = require("./remote-events");
|
|
29
28
|
const upsyncer_1 = require("./upsyncer");
|
|
30
29
|
const utils_for_observables_1 = require("../../../lib-common/utils-for-observables");
|
|
@@ -39,39 +38,48 @@ class SyncedStore {
|
|
|
39
38
|
this.versioned = true;
|
|
40
39
|
this.nodes = new common_1.NodesContainer();
|
|
41
40
|
this.events = new utils_for_observables_1.Broadcast();
|
|
42
|
-
|
|
43
|
-
this.
|
|
44
|
-
this.uploader = new upsyncer_1.UpSyncer(this.remoteStorage, this.logError, this.broadcastUpSyncEvent.bind(this));
|
|
41
|
+
this.remoteEvents = new remote_events_1.RemoteEvents(this.remoteStorage, this.files, this.broadcastNodeEvent.bind(this), this.logError);
|
|
42
|
+
this.uploader = new upsyncer_1.UpSyncer(this.remoteStorage, this.logError);
|
|
45
43
|
Object.seal(this);
|
|
46
44
|
}
|
|
47
|
-
static async makeAndStart(path, user, getSigner, getStorages, cryptor, remoteServiceUrl,
|
|
48
|
-
const remote =
|
|
49
|
-
const objFiles = await obj_files_1.ObjFiles.makeFor(path,
|
|
45
|
+
static async makeAndStart(path, user, getSigner, getStorages, cryptor, remoteServiceUrl, net, logError) {
|
|
46
|
+
const remote = service_1.StorageOwner.make(user, getSigner, remoteServiceUrl, net);
|
|
47
|
+
const objFiles = await obj_files_1.ObjFiles.makeFor(path, remote, logError);
|
|
50
48
|
const s = new SyncedStore(objFiles, remote, getStorages, cryptor, logError);
|
|
51
49
|
s.uploader.start();
|
|
50
|
+
// XXX ??
|
|
51
|
+
// s.remoteEvents.startAbsorbingRemoteEvents();
|
|
52
52
|
return {
|
|
53
|
-
syncedStore: common_1.wrapSyncStorageImplementation(s),
|
|
53
|
+
syncedStore: (0, common_1.wrapSyncStorageImplementation)(s),
|
|
54
54
|
startObjProcs: () => {
|
|
55
55
|
s.remoteEvents.startAbsorbingRemoteEvents();
|
|
56
56
|
}
|
|
57
57
|
};
|
|
58
58
|
}
|
|
59
|
+
static async makeAndStartWithoutRemote(path, user, getStorages, cryptor, remoteServiceUrl, net, logError) {
|
|
60
|
+
const { remote, setMid } = service_1.StorageOwner.makeBeforeMidSetup(user, remoteServiceUrl, net);
|
|
61
|
+
const objFiles = await obj_files_1.ObjFiles.makeFor(path, remote, logError);
|
|
62
|
+
const s = new SyncedStore(objFiles, remote, getStorages, cryptor, logError);
|
|
63
|
+
// XXX ??
|
|
64
|
+
// s.remoteEvents.startAbsorbingRemoteEvents();
|
|
65
|
+
return {
|
|
66
|
+
syncedStore: (0, common_1.wrapSyncStorageImplementation)(s),
|
|
67
|
+
setupRemoteAndStartObjProcs: getSigner => {
|
|
68
|
+
setMid(getSigner);
|
|
69
|
+
s.uploader.start();
|
|
70
|
+
s.remoteEvents.startAbsorbingRemoteEvents();
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
}
|
|
59
74
|
getNodeEvents() {
|
|
60
75
|
return this.events.event$;
|
|
61
76
|
}
|
|
62
|
-
broadcastNodeEvent(objId, parentObjId, event) {
|
|
63
|
-
this.events.next({ objId, parentObjId, event });
|
|
64
|
-
}
|
|
65
|
-
broadcastUpSyncEvent(objId, task) {
|
|
66
|
-
const node = this.nodes.get(objId);
|
|
67
|
-
if (!node) {
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
node.broadcastUpSyncEvent(task);
|
|
77
|
+
broadcastNodeEvent(objId, parentObjId, childObjId, event) {
|
|
78
|
+
this.events.next({ objId, parentObjId, childObjId, event });
|
|
71
79
|
}
|
|
72
80
|
storageForLinking(type, location) {
|
|
73
81
|
if (type === 'synced') {
|
|
74
|
-
return common_1.wrapStorageImplementation(this);
|
|
82
|
+
return (0, common_1.wrapStorageImplementation)(this);
|
|
75
83
|
}
|
|
76
84
|
else if (type === 'share') {
|
|
77
85
|
return this.getStorages('share', location);
|
|
@@ -80,18 +88,107 @@ class SyncedStore {
|
|
|
80
88
|
throw new Error(`Getting ${type} storage is not implemented in local storage.`);
|
|
81
89
|
}
|
|
82
90
|
}
|
|
83
|
-
async
|
|
91
|
+
async status(objId) {
|
|
92
|
+
const obj = await this.getObjOrThrow(objId, true);
|
|
93
|
+
return obj.syncStatus();
|
|
94
|
+
}
|
|
95
|
+
async adoptRemote(objId, opts) {
|
|
96
|
+
const obj = await this.getObjOrThrow(objId);
|
|
97
|
+
const objStatus = obj.statusObj();
|
|
98
|
+
await objStatus.adoptRemoteVersion(opts === null || opts === void 0 ? void 0 : opts.remoteVersion, opts === null || opts === void 0 ? void 0 : opts.dropLocalVer);
|
|
99
|
+
if (opts && opts.download) {
|
|
100
|
+
// XXX this needs implementation
|
|
101
|
+
throw new Error('SyncedStore.adoptRemote() with download option needs implementation, probably using SyncedStore.download().');
|
|
102
|
+
}
|
|
103
|
+
this.files.scheduleGC(obj);
|
|
104
|
+
return objStatus.syncStatus().synced.latest;
|
|
105
|
+
}
|
|
106
|
+
async updateStatusInfo(objId) {
|
|
107
|
+
const obj = await this.getObjOrThrow(objId, true);
|
|
108
|
+
try {
|
|
109
|
+
const statusOnServer = await this.remoteStorage.getObjStatus(objId);
|
|
110
|
+
const objStatus = obj.statusObj();
|
|
111
|
+
await objStatus.recordStatusFromServer(statusOnServer);
|
|
112
|
+
return objStatus.syncStatus();
|
|
113
|
+
}
|
|
114
|
+
catch (exc) {
|
|
115
|
+
if ((exc.type === 'storage')
|
|
116
|
+
&& exc.objNotFound) {
|
|
117
|
+
const objStatus = obj.statusObj();
|
|
118
|
+
await objStatus.recordStatusFromServer({});
|
|
119
|
+
return objStatus.syncStatus();
|
|
120
|
+
}
|
|
121
|
+
throw exc;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
async isObjOnDisk(objId) {
|
|
84
125
|
const obj = await this.files.findObj(objId);
|
|
126
|
+
return !!obj;
|
|
127
|
+
}
|
|
128
|
+
async isRemoteVersionOnDisk(objId, version) {
|
|
129
|
+
var _a;
|
|
130
|
+
const obj = await this.getObjOrThrow(objId, true);
|
|
131
|
+
const status = obj.statusObj();
|
|
132
|
+
const { remote } = status.syncStatus();
|
|
133
|
+
if (((remote === null || remote === void 0 ? void 0 : remote.latest) !== version)
|
|
134
|
+
|| !((_a = remote.archived) === null || _a === void 0 ? void 0 : _a.includes(version))) {
|
|
135
|
+
throw (0, exceptions_1.makeObjVersionNotFoundExc)(objId, version);
|
|
136
|
+
}
|
|
137
|
+
// XXX
|
|
138
|
+
// - get state of file
|
|
139
|
+
throw new Error('SyncedStore.isRemoteVersionOnDisk() not implemented.');
|
|
140
|
+
}
|
|
141
|
+
download(objId, version) {
|
|
142
|
+
// XXX
|
|
143
|
+
// - check if on disk
|
|
144
|
+
// - download header
|
|
145
|
+
// - want result of DC-296, calculation of diff to download, relative to
|
|
146
|
+
// latest version on the disk, using headers of both versions.
|
|
147
|
+
throw new Error('SyncedStore.download() not implemented.');
|
|
148
|
+
}
|
|
149
|
+
async upload(objId, localVersion, uploadVersion, uploadHeader, createOnRemote) {
|
|
150
|
+
const obj = await this.getObjOrThrow(objId, true);
|
|
151
|
+
const syncedBase = await obj.combineLocalBaseIfPresent(localVersion);
|
|
152
|
+
if (uploadHeader) {
|
|
153
|
+
await obj.saveUploadHeaderFile(uploadHeader);
|
|
154
|
+
}
|
|
155
|
+
await this.uploader.uploadFromDisk(obj, localVersion, uploadVersion, uploadHeader === null || uploadHeader === void 0 ? void 0 : uploadHeader.uploadHeader, syncedBase, createOnRemote);
|
|
156
|
+
await obj.recordUploadCompletion(localVersion, uploadVersion, (uploadHeader ? {
|
|
157
|
+
newHeader: uploadHeader.uploadHeader,
|
|
158
|
+
originalHeader: uploadHeader.localHeader
|
|
159
|
+
} : undefined));
|
|
160
|
+
if (localVersion > uploadVersion) {
|
|
161
|
+
await obj.removeLocalVersionFilesLessThan(localVersion);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
async uploadObjRemoval(objId) {
|
|
165
|
+
if (!objId) {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
const obj = await this.getObjOrThrow(objId, true);
|
|
169
|
+
const status = obj.statusObj();
|
|
170
|
+
if (status.neverUploaded()) {
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
if (await status.clearPostponeFlagInRemovalOnRemote()) {
|
|
174
|
+
await this.uploader.removeCurrentVersionOf(obj);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
dropCachedLocalObjVersionsLessOrEqual(objId, version) {
|
|
178
|
+
const obj = this.files.getObjInCache(objId);
|
|
85
179
|
if (!obj) {
|
|
86
180
|
return;
|
|
87
181
|
}
|
|
88
|
-
|
|
182
|
+
obj.dropCachedLocalObjVersionsLessOrEqual(version);
|
|
183
|
+
}
|
|
184
|
+
async archiveVersionOnServer(objId, version) {
|
|
185
|
+
await this.remoteStorage.archiveObjVersion(objId, version);
|
|
89
186
|
}
|
|
90
187
|
getRootKeyDerivParamsFromServer() {
|
|
91
188
|
return this.remoteStorage.getKeyDerivParams();
|
|
92
189
|
}
|
|
93
190
|
async generateNewObjId() {
|
|
94
|
-
const nonce = await random_node_1.bytes(xsp_files_1.NONCE_LENGTH);
|
|
191
|
+
const nonce = await (0, random_node_1.bytes)(xsp_files_1.NONCE_LENGTH);
|
|
95
192
|
const id = buffer_utils_1.base64urlSafe.pack(nonce);
|
|
96
193
|
if (this.nodes.reserveId(id)) {
|
|
97
194
|
return id;
|
|
@@ -105,53 +202,56 @@ class SyncedStore {
|
|
|
105
202
|
if (obj) {
|
|
106
203
|
return obj;
|
|
107
204
|
}
|
|
205
|
+
// XXX
|
|
206
|
+
// - can we create object by getting obj status
|
|
108
207
|
return await this.files.makeByDownloadingCurrentVersion(objId);
|
|
109
208
|
}
|
|
110
|
-
async
|
|
209
|
+
async getObjOrThrow(objId, allowArchived = false) {
|
|
111
210
|
const obj = await this.objFromDiskOrDownload(objId);
|
|
112
|
-
if (obj.isArchived()) {
|
|
113
|
-
throw exceptions_1.makeObjNotFoundExc(objId);
|
|
211
|
+
if (!allowArchived && obj.statusObj().isArchived()) {
|
|
212
|
+
throw (0, exceptions_1.makeObjNotFoundExc)(objId);
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
return obj;
|
|
114
216
|
}
|
|
115
|
-
return obj;
|
|
116
217
|
}
|
|
117
|
-
async
|
|
118
|
-
const obj = await this.
|
|
119
|
-
|
|
120
|
-
|
|
218
|
+
async getObjSrc(objId, version, allowArchived = false) {
|
|
219
|
+
const obj = await this.getObjOrThrow(objId, allowArchived);
|
|
220
|
+
if (!version) {
|
|
221
|
+
version = obj.statusObj().getCurrentLocalOrSynced();
|
|
222
|
+
}
|
|
223
|
+
return obj.getObjSrcFromLocalAndSyncedBranch(version);
|
|
121
224
|
}
|
|
122
|
-
async
|
|
123
|
-
const obj = await this.
|
|
124
|
-
return obj.
|
|
225
|
+
async getObjSrcOfRemoteVersion(objId, version) {
|
|
226
|
+
const obj = await this.getObjOrThrow(objId);
|
|
227
|
+
return obj.getObjSrcFromRemoteAndSyncedBranch(version);
|
|
125
228
|
}
|
|
126
229
|
async saveObj(objId, version, encSub) {
|
|
127
230
|
if (version === 1) {
|
|
128
231
|
const obj = await this.files.findObj(objId);
|
|
129
232
|
if (obj) {
|
|
130
|
-
throw exceptions_1.makeObjExistsExc(objId);
|
|
233
|
+
throw (0, exceptions_1.makeObjExistsExc)(objId);
|
|
131
234
|
}
|
|
132
|
-
const { fileWrite
|
|
133
|
-
await fileWrite
|
|
134
|
-
.pipe(this.uploader.tapFileWrite(newObj, true, version))
|
|
135
|
-
.toPromise();
|
|
235
|
+
const { fileWrite$ } = await this.files.saveFirstVersion(objId, encSub);
|
|
236
|
+
await fileWrite$.toPromise();
|
|
136
237
|
}
|
|
137
238
|
else {
|
|
138
|
-
const obj = await this.
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
}
|
|
142
|
-
const { fileWrite$, baseVer } = await obj.saveNewVersion(version, encSub);
|
|
143
|
-
await fileWrite$
|
|
144
|
-
.pipe(this.uploader.tapFileWrite(obj, false, version, baseVer))
|
|
145
|
-
.toPromise();
|
|
239
|
+
const obj = await this.getObjOrThrow(objId);
|
|
240
|
+
const { fileWrite$ } = await obj.saveNewVersion(version, encSub);
|
|
241
|
+
await fileWrite$.toPromise();
|
|
146
242
|
}
|
|
147
243
|
}
|
|
148
244
|
async removeObj(objId) {
|
|
149
|
-
const obj = await this.
|
|
245
|
+
const obj = await this.getObjOrThrow(objId)
|
|
246
|
+
.catch((exc) => {
|
|
247
|
+
if (!exc.objNotFound) {
|
|
248
|
+
throw exc;
|
|
249
|
+
}
|
|
250
|
+
});
|
|
150
251
|
if (!obj) {
|
|
151
252
|
return;
|
|
152
253
|
}
|
|
153
254
|
await obj.removeCurrentVersion();
|
|
154
|
-
await this.uploader.removeCurrentVersionOf(obj);
|
|
155
255
|
}
|
|
156
256
|
async close() {
|
|
157
257
|
try {
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { UploadHeaderChange } from "../../../lib-client/3nstorage/xsp-fs/common";
|
|
2
|
+
export declare const UPLOAD_HEADER_FILE_NAME_EXT = "upload";
|
|
3
|
+
export declare function saveUploadHeaderFile(objFolder: string, headers: UploadHeaderChange): Promise<void>;
|
|
4
|
+
export declare function readUploadHeaderFromFile(objFolder: string, uploadVersion: number): Promise<UploadHeaderChange | undefined>;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
Copyright (C) 2022 3NSoft Inc.
|
|
4
|
+
|
|
5
|
+
This program is free software: you can redistribute it and/or modify it under
|
|
6
|
+
the terms of the GNU General Public License as published by the Free Software
|
|
7
|
+
Foundation, either version 3 of the License, or (at your option) any later
|
|
8
|
+
version.
|
|
9
|
+
|
|
10
|
+
This program is distributed in the hope that it will be useful, but
|
|
11
|
+
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
13
|
+
See the GNU General Public License for more details.
|
|
14
|
+
|
|
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/>.
|
|
17
|
+
*/
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
exports.readUploadHeaderFromFile = exports.saveUploadHeaderFile = exports.UPLOAD_HEADER_FILE_NAME_EXT = void 0;
|
|
20
|
+
const path_1 = require("path");
|
|
21
|
+
const async_fs_node_1 = require("../../../lib-common/async-fs-node");
|
|
22
|
+
const file_1 = require("../../../lib-common/exceptions/file");
|
|
23
|
+
const big_endian_1 = require("../../../lib-common/big-endian");
|
|
24
|
+
const assert_1 = require("../../../lib-common/assert");
|
|
25
|
+
exports.UPLOAD_HEADER_FILE_NAME_EXT = 'upload';
|
|
26
|
+
async function saveUploadHeaderFile(objFolder, headers) {
|
|
27
|
+
const bytes = packUploadHeaderChange(headers);
|
|
28
|
+
await (0, async_fs_node_1.writeFile)(uploadHeaderFilePath(objFolder, headers.uploadVersion), bytes);
|
|
29
|
+
}
|
|
30
|
+
exports.saveUploadHeaderFile = saveUploadHeaderFile;
|
|
31
|
+
async function readUploadHeaderFromFile(objFolder, uploadVersion) {
|
|
32
|
+
try {
|
|
33
|
+
const bytes = await (0, async_fs_node_1.readFile)(uploadHeaderFilePath(objFolder, uploadVersion));
|
|
34
|
+
return unpackUploadHeaderChange(bytes);
|
|
35
|
+
}
|
|
36
|
+
catch (exc) {
|
|
37
|
+
if (exc.code !== file_1.Code.notFound) {
|
|
38
|
+
throw exc;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
exports.readUploadHeaderFromFile = readUploadHeaderFromFile;
|
|
43
|
+
function uploadHeaderFilePath(objFolder, uploadVersion) {
|
|
44
|
+
return (0, path_1.join)(objFolder, `${uploadVersion}.${exports.UPLOAD_HEADER_FILE_NAME_EXT}`);
|
|
45
|
+
}
|
|
46
|
+
function packUploadHeaderChange({ localHeader, localVersion, uploadHeader, uploadVersion }) {
|
|
47
|
+
(0, assert_1.assert)(localHeader.length === uploadHeader.length);
|
|
48
|
+
const bytes = Buffer.allocUnsafe(16 + 2 * localHeader.length);
|
|
49
|
+
(0, big_endian_1.packUintTo8Bytes)(localVersion, bytes, 0);
|
|
50
|
+
(0, big_endian_1.packUintTo8Bytes)(uploadVersion, bytes, 8);
|
|
51
|
+
bytes.set(localHeader, 16);
|
|
52
|
+
bytes.set(uploadHeader, 16 + localHeader.length);
|
|
53
|
+
return bytes;
|
|
54
|
+
}
|
|
55
|
+
function unpackUploadHeaderChange(bytes) {
|
|
56
|
+
const localVersion = (0, big_endian_1.uintFrom8Bytes)(bytes, 0);
|
|
57
|
+
const uploadVersion = (0, big_endian_1.uintFrom8Bytes)(bytes, 8);
|
|
58
|
+
const headerLen = (bytes.length - 16) / 2;
|
|
59
|
+
(0, assert_1.assert)(Number.isInteger(headerLen));
|
|
60
|
+
const localHeader = bytes.slice(16, 16 + headerLen);
|
|
61
|
+
const uploadHeader = bytes.slice(16 + headerLen);
|
|
62
|
+
return { localHeader, localVersion, uploadHeader, uploadVersion };
|
|
63
|
+
}
|
|
64
|
+
Object.freeze(exports);
|
|
@@ -3,20 +3,25 @@ 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 {
|
|
7
|
-
import { ObjId } from "../../../lib-client/3nstorage/xsp-fs/common";
|
|
6
|
+
import { NewVersionUpload } from "./obj-status";
|
|
8
7
|
export declare type FileWriteTapOperator = MonoTypeOperatorFunction<FileWrite[]>;
|
|
9
|
-
export declare type BroadcastUpSyncEvent = (objId: ObjId, task: UpSyncTaskInfo) => void;
|
|
10
8
|
export declare class UpSyncer {
|
|
11
9
|
private readonly remoteStorage;
|
|
12
10
|
private readonly logError;
|
|
13
|
-
private readonly broadcastUpSyncEvent;
|
|
14
11
|
private readonly execPools;
|
|
15
|
-
|
|
16
|
-
constructor(remoteStorage: StorageOwner, logError: LogError, broadcastUpSyncEvent: BroadcastUpSyncEvent);
|
|
17
|
-
private getOrMakeUploadsFor;
|
|
12
|
+
constructor(remoteStorage: StorageOwner, logError: LogError);
|
|
18
13
|
start(): void;
|
|
19
14
|
stop(): Promise<void>;
|
|
15
|
+
/**
|
|
16
|
+
* Creates an rxjs operator to tap saving process, starting upload while
|
|
17
|
+
* writing is ongoing.
|
|
18
|
+
*/
|
|
20
19
|
tapFileWrite(obj: SyncedObj, isNew: boolean, newVersion: number, baseVersion?: number): FileWriteTapOperator;
|
|
21
20
|
removeCurrentVersionOf(obj: SyncedObj): Promise<void>;
|
|
21
|
+
uploadFromDisk(obj: SyncedObj, localVersion: number, uploadVersion: number, uploadHeader: Uint8Array | undefined, syncedBase: number | undefined, createOnRemote: boolean): Promise<void>;
|
|
22
|
+
}
|
|
23
|
+
export interface UploadStatusRecorder {
|
|
24
|
+
recordUploadStart(info: NewVersionUpload): Promise<void>;
|
|
25
|
+
recordUploadCancellation(info: NewVersionUpload): Promise<void>;
|
|
26
|
+
recordUploadInterimState(info: NewVersionUpload): Promise<void>;
|
|
22
27
|
}
|