core-3nweb-client-lib 0.44.2 → 0.44.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.
Files changed (33) hide show
  1. package/build/api-defs/files.d.ts +20 -5
  2. package/build/core/id-manager/key-storage.d.ts +1 -0
  3. package/build/core/id-manager/key-storage.js +18 -3
  4. package/build/core/storage/synced/remote-events.d.ts +3 -0
  5. package/build/core/storage/synced/remote-events.js +24 -1
  6. package/build/core/storage/synced/storage.d.ts +1 -0
  7. package/build/core/storage/synced/storage.js +5 -2
  8. package/build/core-ipc/file.d.ts +4 -0
  9. package/build/core-ipc/file.js +22 -1
  10. package/build/core-ipc/fs.js +13 -11
  11. package/build/lib-client/cryptor/cryptor-wasm.js +1 -1
  12. package/build/lib-client/cryptor/cryptor.wasm +0 -0
  13. package/build/lib-client/fs-utils/files.js +5 -1
  14. package/build/lib-client/xsp-fs/common.d.ts +1 -0
  15. package/build/lib-client/xsp-fs/common.js +1 -0
  16. package/build/lib-client/xsp-fs/file-node.d.ts +2 -1
  17. package/build/lib-client/xsp-fs/file-node.js +8 -4
  18. package/build/lib-client/xsp-fs/file.d.ts +1 -0
  19. package/build/lib-client/xsp-fs/file.js +3 -0
  20. package/build/lib-client/xsp-fs/folder-node.d.ts +3 -2
  21. package/build/lib-client/xsp-fs/folder-node.js +48 -61
  22. package/build/lib-client/xsp-fs/fs.d.ts +3 -2
  23. package/build/lib-client/xsp-fs/fs.js +5 -2
  24. package/build/lib-client/xsp-fs/link-node.d.ts +1 -0
  25. package/build/lib-client/xsp-fs/link-node.js +3 -0
  26. package/build/lib-client/xsp-fs/node-in-fs.d.ts +1 -1
  27. package/build/lib-client/xsp-fs/node-in-fs.js +14 -12
  28. package/build/lib-common/exceptions/error.js +2 -1
  29. package/build/protos/asmail.proto.js +158 -158
  30. package/build/protos/fs.proto.js +158 -158
  31. package/package.json +1 -1
  32. package/protos/file.proto +4 -0
  33. package/protos/fs.proto +7 -4
@@ -622,6 +622,12 @@ declare namespace web3n.files {
622
622
 
623
623
  interface ReadonlyFileSyncAPI {
624
624
 
625
+ /**
626
+ * When connection exception is caught, use this to await connection to continue.
627
+ * This returns a promise, resolvable when connected to storage server.
628
+ */
629
+ whenConnected(): Promise<void>;
630
+
625
631
  /**
626
632
  * Returns synchronization status of this object.
627
633
  * @param skipServerCheck is optional parameter to skip server check, that may be handy in offline
@@ -1404,6 +1410,12 @@ declare namespace web3n.files {
1404
1410
 
1405
1411
  interface ReadonlyFSSyncAPI {
1406
1412
 
1413
+ /**
1414
+ * When connection exception is caught, use this to await connection to continue.
1415
+ * This returns a promise, resolvable when connected to storage server.
1416
+ */
1417
+ whenConnected(): Promise<void>;
1418
+
1407
1419
  /**
1408
1420
  * Returns synchronization status of item at given path.
1409
1421
  * @param path
@@ -1481,7 +1493,7 @@ declare namespace web3n.files {
1481
1493
  */
1482
1494
  getRemoteFolderItem(path: string, remoteItemName: string, remoteVersion?: number): Promise<ReadonlyFS>;
1483
1495
 
1484
- // XXX method to work around demaged files
1496
+ // XXX method to work around damaged files
1485
1497
  // reloadFromServer(path: string): Promise<SyncStatus>;
1486
1498
 
1487
1499
  }
@@ -1657,15 +1669,18 @@ declare namespace web3n.files {
1657
1669
 
1658
1670
  /**
1659
1671
  * This method is for resolving conflicts on folders.
1660
- * It merges folder changes from remote version.
1672
+ * It absorbs folder changes done in remote version.
1661
1673
  * Returns new local version, if there were remote items to adopt and their were added to local state.
1662
1674
  * @param path
1663
1675
  * @param opts
1664
1676
  */
1665
- mergeFolderCurrentAndRemoteVersions(
1666
- path: string, opts?: OptionsToMergeFolderVersions
1677
+ absorbRemoteFolderChanges(
1678
+ path: string, opts?: OptionsToAdoptRemoteFolderChanges
1667
1679
  ): Promise<number|undefined>;
1668
1680
 
1681
+ // XXX
1682
+ // makeSnapshot(path: string); // -> snapshot points and archives current versions of tree elements
1683
+
1669
1684
  }
1670
1685
 
1671
1686
  interface OptionsToAdoptRemoteItem {
@@ -1688,7 +1703,7 @@ declare namespace web3n.files {
1688
1703
  newItemName?: string;
1689
1704
  }
1690
1705
 
1691
- interface OptionsToMergeFolderVersions {
1706
+ interface OptionsToAdoptRemoteFolderChanges {
1692
1707
  /**
1693
1708
  * Folder's local version. If not given, current local version is used.
1694
1709
  */
@@ -17,5 +17,6 @@ export declare class IdKeysStorage {
17
17
  };
18
18
  getSavedKey(): Promise<JsonKey | undefined>;
19
19
  private setStorageFS;
20
+ private ensureDataFolderIsUploaded;
20
21
  }
21
22
  export {};
@@ -72,9 +72,6 @@ class IdKeysStorage {
72
72
  this.fs = fs;
73
73
  if (keysToSave) {
74
74
  await this.fs.writeJSONFile(LOGIN_KEY_FILE_NAME, keysToSave);
75
- // XXX must add work with not-online condition
76
- await this.fs.v.sync.upload(LOGIN_KEY_FILE_NAME);
77
- await this.fs.v.sync.upload('');
78
75
  }
79
76
  else {
80
77
  try {
@@ -84,6 +81,24 @@ class IdKeysStorage {
84
81
  throw (0, error_1.errWithCause)(exc, `Fail expection read of login MailerId keys from the storage`);
85
82
  }
86
83
  }
84
+ this.ensureDataFolderIsUploaded();
85
+ }
86
+ async ensureDataFolderIsUploaded() {
87
+ try {
88
+ const fileStatus = await this.fs.v.sync.status(LOGIN_KEY_FILE_NAME, false);
89
+ if (fileStatus.state === 'unsynced') {
90
+ await this.fs.v.sync.upload(LOGIN_KEY_FILE_NAME);
91
+ }
92
+ const folderStatus = await this.fs.v.sync.status('', true);
93
+ if (folderStatus.state === 'unsynced') {
94
+ await this.fs.v.sync.upload('');
95
+ }
96
+ }
97
+ catch (exc) {
98
+ if (exc.type === 'connect') {
99
+ return this.fs.v.sync.whenConnected().then(() => this.ensureDataFolderIsUploaded());
100
+ }
101
+ }
87
102
  }
88
103
  }
89
104
  exports.IdKeysStorage = IdKeysStorage;
@@ -19,10 +19,13 @@ export declare class RemoteEvents {
19
19
  private readonly connectionEvents;
20
20
  readonly connectionEvent$: Observable<StorageConnectionStatus>;
21
21
  private readonly wsProc;
22
+ private deferredConnection;
22
23
  constructor(remoteStorage: StorageOwner, files: ObjFiles, broadcastNodeEvent: Storage['broadcastNodeEvent'], logError: LogError);
23
24
  private makeProc;
24
25
  startListening(): void;
25
26
  close(): Promise<void>;
27
+ whenConnected(): Promise<void>;
28
+ private signalConnected;
26
29
  private absorbObjChange;
27
30
  private absorbObjRemoval;
28
31
  private absorbObjVersionArchival;
@@ -21,6 +21,7 @@ const rxjs_1 = require("rxjs");
21
21
  const owner_1 = require("../../../lib-common/service-api/3nstorage/owner");
22
22
  const operators_1 = require("rxjs/operators");
23
23
  const ws_ipc_1 = require("../../../lib-common/ipc/ws-ipc");
24
+ const deferred_1 = require("../../../lib-common/processes/deferred");
24
25
  function toStorageConnectionStatus(status, params) {
25
26
  return (0, ws_ipc_1.addToStatus)(status, {
26
27
  service: 'storage',
@@ -40,13 +41,25 @@ class RemoteEvents {
40
41
  this.logError = logError;
41
42
  this.connectionEvents = new rxjs_1.Subject();
42
43
  this.connectionEvent$ = this.connectionEvents.asObservable().pipe((0, operators_1.share)());
44
+ this.deferredConnection = (0, deferred_1.defer)();
43
45
  this.wsProc = new ws_ipc_1.WebSocketListening(SERVER_EVENTS_RESTART_WAIT_SECS, this.makeProc.bind(this));
44
46
  Object.seal(this);
45
47
  }
46
48
  makeProc() {
47
49
  return (0, rxjs_1.from)(this.remoteStorage.openEventSource().then(({ client, heartbeat }) => {
50
+ this.signalConnected();
48
51
  heartbeat.subscribe({
49
- next: ev => this.connectionEvents.next(toStorageConnectionStatus(ev))
52
+ next: ev => {
53
+ this.connectionEvents.next(toStorageConnectionStatus(ev));
54
+ if (ev.type === 'heartbeat') {
55
+ this.signalConnected();
56
+ }
57
+ else if ((ev.type === 'heartbeat-skip') || (ev.type === 'disconnected')) {
58
+ if (!this.deferredConnection) {
59
+ this.deferredConnection = (0, deferred_1.defer)();
60
+ }
61
+ }
62
+ }
50
63
  });
51
64
  return [
52
65
  this.absorbObjChange(client),
@@ -65,6 +78,16 @@ class RemoteEvents {
65
78
  this.connectionEvents.complete();
66
79
  this.wsProc.close();
67
80
  }
81
+ async whenConnected() {
82
+ var _a;
83
+ return (_a = this.deferredConnection) === null || _a === void 0 ? void 0 : _a.promise;
84
+ }
85
+ signalConnected() {
86
+ if (this.deferredConnection) {
87
+ this.deferredConnection.resolve();
88
+ this.deferredConnection = undefined;
89
+ }
90
+ }
68
91
  absorbObjChange(client) {
69
92
  return (new rxjs_1.Observable(obs => client.subscribe(owner_1.events.objChanged.EVENT_NAME, obs)))
70
93
  .pipe((0, operators_1.mergeMap)(async ({ newVer: newRemoteVersion, objId }) => {
@@ -62,5 +62,6 @@ export declare class SyncedStore implements ISyncedStorage {
62
62
  suspendNetworkActivity(): void;
63
63
  resumeNetworkActivity(): void;
64
64
  get connectionEvent$(): Observable<import("./remote-events").StorageConnectionStatus>;
65
+ whenConnected(): Promise<void>;
65
66
  }
66
67
  export {};
@@ -194,7 +194,7 @@ class SyncedStore {
194
194
  return obj.getObjSrcFromLocalAndSyncedBranch(version);
195
195
  }
196
196
  async getObjSrcOfRemoteVersion(objId, version) {
197
- const obj = await this.getObjOrThrow(objId);
197
+ const obj = await this.getObjOrThrow(objId, true);
198
198
  return obj.getObjSrcFromRemoteAndSyncedBranch(version);
199
199
  }
200
200
  async saveObj(objId, version, encSub) {
@@ -225,7 +225,7 @@ class SyncedStore {
225
225
  await obj.removeCurrentVersion();
226
226
  }
227
227
  async getNumOfBytesNeedingDownload(objId, version) {
228
- const obj = await this.getObjOrThrow(objId);
228
+ const obj = await this.getObjOrThrow(objId, true);
229
229
  return obj.getNumOfBytesNeedingDownload(version);
230
230
  }
231
231
  async close() {
@@ -248,6 +248,9 @@ class SyncedStore {
248
248
  get connectionEvent$() {
249
249
  return this.remoteEvents.connectionEvent$;
250
250
  }
251
+ whenConnected() {
252
+ return this.remoteEvents.whenConnected();
253
+ }
251
254
  }
252
255
  exports.SyncedStore = SyncedStore;
253
256
  Object.freeze(SyncedStore.prototype);
@@ -151,6 +151,10 @@ export declare namespace vGetByteSink {
151
151
  function wrapService(fn: WritableFileVersionedAPI['getByteSink'], expServices: CoreSideServices): ExposedFn;
152
152
  function makeCaller(caller: Caller, objPath: string[]): WritableFileVersionedAPI['getByteSink'];
153
153
  }
154
+ export declare namespace vsWhenConnected {
155
+ function wrapService(fn: ReadonlyFileSyncAPI['whenConnected']): ExposedFn;
156
+ function makeCaller(caller: Caller, objPath: string[]): ReadonlyFileSyncAPI['whenConnected'];
157
+ }
154
158
  export declare namespace vsStartDownload {
155
159
  const replyType: ProtoType<{
156
160
  startedDownload?: {
@@ -16,7 +16,7 @@
16
16
  this program. If not, see <http://www.gnu.org/licenses/>.
17
17
  */
18
18
  Object.defineProperty(exports, "__esModule", { value: true });
19
- exports.vsDiffCurrentAndRemoteVersions = exports.vListVersions = exports.vsUpload = exports.vsStartUpload = exports.vsStartDownload = exports.vGetByteSink = exports.updateXAttrs = exports.vGetByteSource = exports.vReadJSON = exports.vReadTxt = exports.vReadBytes = exports.vListXAttrs = exports.vGetXAttr = exports.vStat = exports.readBytes = exports.fileMsgType = void 0;
19
+ exports.vsDiffCurrentAndRemoteVersions = exports.vListVersions = exports.vsUpload = exports.vsStartUpload = exports.vsStartDownload = exports.vsWhenConnected = exports.vGetByteSink = exports.updateXAttrs = exports.vGetByteSource = exports.vReadJSON = exports.vReadTxt = exports.vReadBytes = exports.vListXAttrs = exports.vGetXAttr = exports.vStat = exports.readBytes = exports.fileMsgType = void 0;
20
20
  exports.makeFileCaller = makeFileCaller;
21
21
  exports.exposeFileService = exposeFileService;
22
22
  exports.packStats = packStats;
@@ -100,6 +100,7 @@ function makeFileCaller(caller, fileMsg) {
100
100
  if (fileMsg.isSynced) {
101
101
  const vsPath = (0, protobuf_msg_1.methodPathFor)(vPath, 'sync');
102
102
  file.v.sync = {
103
+ whenConnected: vsWhenConnected.makeCaller(caller, vsPath),
103
104
  status: vsStatus.makeCaller(caller, vsPath),
104
105
  isRemoteVersionOnDisk: vsIsRemoteVersionOnDisk.makeCaller(caller, vsPath),
105
106
  startDownload: vsStartDownload.makeCaller(caller, vsPath),
@@ -156,6 +157,7 @@ function exposeFileService(file, expServices) {
156
157
  }
157
158
  if (file.v.sync) {
158
159
  implExp.v.sync = {
160
+ whenConnected: vsWhenConnected.wrapService(file.v.sync.whenConnected),
159
161
  status: vsStatus.wrapService(file.v.sync.status),
160
162
  isRemoteVersionOnDisk: vsIsRemoteVersionOnDisk.wrapService(file.v.sync.isRemoteVersionOnDisk),
161
163
  startDownload: vsStartDownload.wrapService(file.v.sync.startDownload),
@@ -1084,6 +1086,25 @@ var vGetByteSink;
1084
1086
  vGetByteSink.makeCaller = makeCaller;
1085
1087
  })(vGetByteSink || (exports.vGetByteSink = vGetByteSink = {}));
1086
1088
  Object.freeze(vGetByteSink);
1089
+ var vsWhenConnected;
1090
+ (function (vsWhenConnected) {
1091
+ function wrapService(fn) {
1092
+ return buf => {
1093
+ const promise = fn();
1094
+ return { promise };
1095
+ };
1096
+ }
1097
+ vsWhenConnected.wrapService = wrapService;
1098
+ function makeCaller(caller, objPath) {
1099
+ const path = (0, protobuf_msg_1.methodPathFor)(objPath, 'whenConnected');
1100
+ return () => caller
1101
+ .startPromiseCall(path, undefined)
1102
+ .then(noop);
1103
+ }
1104
+ vsWhenConnected.makeCaller = makeCaller;
1105
+ })(vsWhenConnected || (exports.vsWhenConnected = vsWhenConnected = {}));
1106
+ Object.freeze(vsWhenConnected);
1107
+ function noop() { }
1087
1108
  var vsStatus;
1088
1109
  (function (vsStatus) {
1089
1110
  function wrapService(fn) {
@@ -101,6 +101,7 @@ function makeFSCaller(caller, fsMsg) {
101
101
  if (fsMsg.isSynced) {
102
102
  const vsPath = (0, protobuf_msg_1.methodPathFor)(vPath, 'sync');
103
103
  fs.v.sync = {
104
+ whenConnected: file.vsWhenConnected.makeCaller(caller, vsPath),
104
105
  status: vsStatus.makeCaller(caller, vsPath),
105
106
  isRemoteVersionOnDisk: vsIsRemoteVersionOnDisk.makeCaller(caller, vsPath),
106
107
  startDownload: vsDownload.makeCaller(caller, vsPath),
@@ -116,7 +117,7 @@ function makeFSCaller(caller, fsMsg) {
116
117
  fs.v.sync.startUpload = vsStartUpload.makeCaller(caller, vsPath);
117
118
  fs.v.sync.upload = vsUpload.makeCaller(caller, vsPath);
118
119
  fs.v.sync.adoptRemoteFolderItem = vsAdoptRemoteFolderItem.makeCaller(caller, vsPath);
119
- fs.v.sync.mergeFolderCurrentAndRemoteVersions = vsMergeFolderCurrentAndRemoteVersions.makeCaller(caller, vsPath);
120
+ fs.v.sync.absorbRemoteFolderChanges = vsAbsorbRemoteFolderChanges.makeCaller(caller, vsPath);
120
121
  }
121
122
  }
122
123
  }
@@ -186,6 +187,7 @@ function exposeFSService(fs, expServices) {
186
187
  }
187
188
  if (fs.v.sync) {
188
189
  implExp.v.sync = {
190
+ whenConnected: file.vsWhenConnected.wrapService(fs.v.sync.whenConnected),
189
191
  status: vsStatus.wrapService(fs.v.sync.status),
190
192
  isRemoteVersionOnDisk: vsIsRemoteVersionOnDisk.wrapService(fs.v.sync.isRemoteVersionOnDisk),
191
193
  startDownload: vsDownload.wrapService(fs.v.sync.startDownload),
@@ -201,7 +203,7 @@ function exposeFSService(fs, expServices) {
201
203
  implExp.v.sync.startUpload = vsStartUpload.wrapService(fs.v.sync.startUpload);
202
204
  implExp.v.sync.upload = vsUpload.wrapService(fs.v.sync.upload);
203
205
  implExp.v.sync.adoptRemoteFolderItem = vsAdoptRemoteFolderItem.wrapService(fs.v.sync.adoptRemoteFolderItem);
204
- implExp.v.sync.mergeFolderCurrentAndRemoteVersions = vsMergeFolderCurrentAndRemoteVersions.wrapService(fs.v.sync.mergeFolderCurrentAndRemoteVersions);
206
+ implExp.v.sync.absorbRemoteFolderChanges = vsAbsorbRemoteFolderChanges.wrapService(fs.v.sync.absorbRemoteFolderChanges);
205
207
  }
206
208
  }
207
209
  }
@@ -1977,9 +1979,9 @@ var vsAdoptRemoteFolderItem;
1977
1979
  vsAdoptRemoteFolderItem.makeCaller = makeCaller;
1978
1980
  })(vsAdoptRemoteFolderItem || (vsAdoptRemoteFolderItem = {}));
1979
1981
  Object.freeze(vsAdoptRemoteFolderItem);
1980
- var vsMergeFolderCurrentAndRemoteVersions;
1981
- (function (vsMergeFolderCurrentAndRemoteVersions) {
1982
- const requestType = protobuf_type_1.ProtoType.for(fs_proto_1.fs.MergeFolderCurrentAndRemoteVersionsRequestBody);
1982
+ var vsAbsorbRemoteFolderChanges;
1983
+ (function (vsAbsorbRemoteFolderChanges) {
1984
+ const requestType = protobuf_type_1.ProtoType.for(fs_proto_1.fs.AbsorbRemoteFolderChangesRequestBody);
1983
1985
  function optionsFromMsg(msg) {
1984
1986
  if (!msg) {
1985
1987
  return;
@@ -2000,7 +2002,7 @@ var vsMergeFolderCurrentAndRemoteVersions;
2000
2002
  postfixForNameOverlaps: (0, protobuf_msg_1.toOptVal)(opts.postfixForNameOverlaps),
2001
2003
  };
2002
2004
  }
2003
- const replyType = protobuf_type_1.ProtoType.for(fs_proto_1.fs.MergeFolderCurrentAndRemoteVersionsReplyBody);
2005
+ const replyType = protobuf_type_1.ProtoType.for(fs_proto_1.fs.AbsorbRemoteFolderChangesReplyBody);
2004
2006
  function wrapService(fn) {
2005
2007
  return buf => {
2006
2008
  const { path, opts } = requestType.unpack(buf);
@@ -2009,16 +2011,16 @@ var vsMergeFolderCurrentAndRemoteVersions;
2009
2011
  return { promise };
2010
2012
  };
2011
2013
  }
2012
- vsMergeFolderCurrentAndRemoteVersions.wrapService = wrapService;
2014
+ vsAbsorbRemoteFolderChanges.wrapService = wrapService;
2013
2015
  function makeCaller(caller, objPath) {
2014
- const ipcPath = (0, protobuf_msg_1.methodPathFor)(objPath, 'mergeFolderCurrentAndRemoteVersions');
2016
+ const ipcPath = (0, protobuf_msg_1.methodPathFor)(objPath, 'absorbRemoteFolderChanges');
2015
2017
  return (path, opts) => caller
2016
2018
  .startPromiseCall(ipcPath, requestType.pack({ path, opts: optionsToMsg(opts) }))
2017
2019
  .then(buf => (0, protobuf_msg_1.valOfOptInt)(replyType.unpack(buf).newVersion));
2018
2020
  }
2019
- vsMergeFolderCurrentAndRemoteVersions.makeCaller = makeCaller;
2020
- })(vsMergeFolderCurrentAndRemoteVersions || (vsMergeFolderCurrentAndRemoteVersions = {}));
2021
- Object.freeze(vsMergeFolderCurrentAndRemoteVersions);
2021
+ vsAbsorbRemoteFolderChanges.makeCaller = makeCaller;
2022
+ })(vsAbsorbRemoteFolderChanges || (vsAbsorbRemoteFolderChanges = {}));
2023
+ Object.freeze(vsAbsorbRemoteFolderChanges);
2022
2024
  var vsAdoptRemote;
2023
2025
  (function (vsAdoptRemote) {
2024
2026
  const requestType = protobuf_type_1.ProtoType.for(fs_proto_1.fs.AdoptRemoteRequestBody);