core-3nweb-client-lib 0.27.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.
Files changed (56) hide show
  1. package/build/api-defs/files.d.ts +4 -7
  2. package/build/core/asmail/inbox/attachments/fs.d.ts +2 -1
  3. package/build/core/asmail/inbox/attachments/fs.js +4 -3
  4. package/build/core/asmail/inbox/index.js +1 -1
  5. package/build/core/id-manager/index.d.ts +43 -0
  6. package/build/core/{id-manager.js → id-manager/index.js} +33 -114
  7. package/build/core/id-manager/key-storage.d.ts +21 -0
  8. package/build/core/id-manager/key-storage.js +96 -0
  9. package/build/core/index.js +21 -23
  10. package/build/core/sign-in.d.ts +1 -2
  11. package/build/core/sign-in.js +4 -13
  12. package/build/core/sign-up.d.ts +2 -0
  13. package/build/core/sign-up.js +2 -1
  14. package/build/core/storage/index.d.ts +4 -2
  15. package/build/core/storage/index.js +36 -57
  16. package/build/core/storage/local/storage.d.ts +1 -1
  17. package/build/core/storage/synced/obj-files-gc.d.ts +1 -4
  18. package/build/core/storage/synced/obj-files-gc.js +1 -18
  19. package/build/core/storage/synced/obj-files.d.ts +9 -1
  20. package/build/core/storage/synced/obj-files.js +41 -33
  21. package/build/core/storage/synced/obj-status.d.ts +18 -7
  22. package/build/core/storage/synced/obj-status.js +148 -83
  23. package/build/core/storage/synced/storage.d.ts +7 -2
  24. package/build/core/storage/synced/storage.js +50 -10
  25. package/build/core/storage/synced/upsyncer.d.ts +4 -4
  26. package/build/core/storage/synced/upsyncer.js +12 -6
  27. package/build/lib-client/3nstorage/exceptions.d.ts +13 -1
  28. package/build/lib-client/3nstorage/exceptions.js +9 -3
  29. package/build/lib-client/3nstorage/service.d.ts +6 -1
  30. package/build/lib-client/3nstorage/service.js +31 -15
  31. package/build/lib-client/3nstorage/util/file-based-json.js +2 -1
  32. package/build/lib-client/3nstorage/util/for-arrays.d.ts +1 -0
  33. package/build/lib-client/3nstorage/util/for-arrays.js +32 -0
  34. package/build/lib-client/3nstorage/xsp-fs/common.d.ts +5 -4
  35. package/build/lib-client/3nstorage/xsp-fs/common.js +1 -0
  36. package/build/lib-client/3nstorage/xsp-fs/file.js +2 -2
  37. package/build/lib-client/3nstorage/xsp-fs/folder-node.d.ts +11 -5
  38. package/build/lib-client/3nstorage/xsp-fs/folder-node.js +232 -68
  39. package/build/lib-client/3nstorage/xsp-fs/fs.js +15 -19
  40. package/build/lib-client/3nstorage/xsp-fs/node-in-fs.d.ts +4 -9
  41. package/build/lib-client/3nstorage/xsp-fs/node-in-fs.js +16 -17
  42. package/build/lib-client/3nstorage/xsp-fs/xsp-payload-v1.js +1 -1
  43. package/build/lib-client/cryptor/cryptor-wasm.js +1 -1
  44. package/build/lib-client/cryptor/cryptor.wasm +0 -0
  45. package/build/lib-client/local-files/device-fs.js +11 -11
  46. package/build/lib-client/user-with-mid-session.d.ts +2 -1
  47. package/build/lib-client/user-with-mid-session.js +7 -1
  48. package/build/lib-common/async-fs-node.js +8 -8
  49. package/build/lib-common/exceptions/file.d.ts +4 -2
  50. package/build/lib-common/exceptions/file.js +24 -58
  51. package/build/lib-common/ipc/generic-ipc.js +5 -4
  52. package/build/lib-common/objs-on-disk/utils.js +1 -1
  53. package/build/lib-common/service-api/3nstorage/owner.d.ts +8 -5
  54. package/build/lib-common/service-api/3nstorage/owner.js +2 -1
  55. package/package.json +3 -2
  56. package/build/core/id-manager.d.ts +0 -46
@@ -85,20 +85,14 @@ async function readRootKeyDerivParamsFromCache(folder) {
85
85
  throw (0, error_1.errWithCause)(err, `Can't read and parse content of obj status file ${KD_PARAMS_FILE_NAME} in folder ${folder}`);
86
86
  }
87
87
  }
88
- /**
89
- * This function tries to get key derivation parameters from cache on a disk.
90
- * If not found, it will ask storage server for it with a provided function.
91
- * @param folder
92
- * @param getFromServer
93
- */
94
- async function getRootKeyDerivParams(folder, getFromServer) {
95
- let params = await readRootKeyDerivParamsFromCache(folder);
96
- if (!params) {
97
- params = await getFromServer();
98
- await fs.writeFile((0, path_1.join)(folder, KD_PARAMS_FILE_NAME), JSON.stringify(params), { encoding: 'utf8' });
99
- }
88
+ async function getAndCacheRootKeyDerivParamsFromServer(folder, getFromServer) {
89
+ const params = await getFromServer();
90
+ await saveRootKeyDerivParamsToDisk(folder, params);
100
91
  return params;
101
92
  }
93
+ async function saveRootKeyDerivParamsToDisk(folder, params) {
94
+ await fs.writeFile((0, path_1.join)(folder, KD_PARAMS_FILE_NAME), JSON.stringify(params), { encoding: 'utf8' });
95
+ }
102
96
  class StorageAndFS {
103
97
  constructor(storage) {
104
98
  this.storage = storage;
@@ -125,32 +119,15 @@ class StorageAndFS {
125
119
  }
126
120
  }
127
121
  }
128
- static async newOrExisting(storage, key) {
129
- var _a, _b;
122
+ static async makeNew(storage, key) {
123
+ var _a;
130
124
  const s = new StorageAndFS(storage);
131
- try {
132
- s.rootFS = await fs_1.XspFS.fromExistingRoot(s.storage, key);
133
- if ((_a = s.rootFS.v) === null || _a === void 0 ? void 0 : _a.sync) {
134
- s.syncedAppDataRoots = await apps_data_1.AppDataFolders.make(s.rootFS);
135
- }
136
- return s;
137
- }
138
- catch (err) {
139
- if (err.objNotFound) {
140
- s.rootFS = await fs_1.XspFS.makeNewRoot(s.storage, key);
141
- await (0, system_folders_1.initSysFolders)(s.rootFS);
142
- if ((_b = s.rootFS.v) === null || _b === void 0 ? void 0 : _b.sync) {
143
- s.syncedAppDataRoots = await apps_data_1.AppDataFolders.make(s.rootFS);
144
- }
145
- return s;
146
- }
147
- else if (err.failedCipherVerification) {
148
- return;
149
- }
150
- else {
151
- throw err;
152
- }
125
+ s.rootFS = await fs_1.XspFS.makeNewRoot(s.storage, key);
126
+ await (0, system_folders_1.initSysFolders)(s.rootFS);
127
+ if ((_a = s.rootFS.v) === null || _a === void 0 ? void 0 : _a.sync) {
128
+ s.syncedAppDataRoots = await apps_data_1.AppDataFolders.make(s.rootFS);
153
129
  }
130
+ return s;
154
131
  }
155
132
  /**
156
133
  * This creates app data folder.
@@ -278,30 +255,32 @@ class Storages {
278
255
  if (!this.local) {
279
256
  return;
280
257
  }
281
- return async (getSigner) => {
282
- if (this.synced) {
283
- return true;
284
- }
285
- const { startObjProcs, syncedStore } = await storage_1.SyncedStore.makeAndStart((0, path_1.join)(storageDir, SYNCED_STORAGE_DIR), user, getSigner, this.storageGetterForSyncedStorage, this.cryptor, () => resolver(user), makeNet(), logError);
286
- this.synced = await StorageAndFS.existing(syncedStore, key);
287
- key.fill(0);
288
- if (!this.synced) {
289
- return false;
290
- }
291
- startObjProcs();
292
- return true;
293
- };
258
+ const { syncedStore, setupRemoteAndStartObjProcs } = await storage_1.SyncedStore.makeAndStartWithoutRemote((0, path_1.join)(storageDir, SYNCED_STORAGE_DIR), user, this.storageGetterForSyncedStorage, this.cryptor, () => resolver(user), makeNet(), logError);
259
+ this.synced = await StorageAndFS.existing(syncedStore, key);
260
+ key.fill(0);
261
+ if (!this.synced) {
262
+ return;
263
+ }
264
+ return setupRemoteAndStartObjProcs;
265
+ }
266
+ async initFromRemote(user, getSigner, generateKey, makeNet, resolver, logError) {
267
+ const storageDir = this.storageDirForUser(user);
268
+ const { startObjProcs, syncedStore } = await storage_1.SyncedStore.makeAndStart((0, path_1.join)(storageDir, SYNCED_STORAGE_DIR), user, getSigner, this.storageGetterForSyncedStorage, this.cryptor, () => resolver(user), makeNet(), logError);
269
+ const params = await getAndCacheRootKeyDerivParamsFromServer(storageDir, syncedStore.getRootKeyDerivParamsFromServer);
270
+ const key = await generateKey(params);
271
+ this.synced = await StorageAndFS.existing(syncedStore, key);
272
+ this.local = await StorageAndFS.makeNew(await storage_2.LocalStorage.makeAndStart((0, path_1.join)(storageDir, LOCAL_STORAGE_DIR), this.storageGetterForLocalStorage, this.cryptor, logError), key);
273
+ key.fill(0);
274
+ startObjProcs();
275
+ return (!!this.synced && !!this.local);
294
276
  }
295
- async initFromRemote(user, getSigner, keyOrGen, makeNet, resolver, logError) {
277
+ async initFreshForNewUser(user, getSigner, params, key, makeNet, resolver, logError) {
296
278
  const storageDir = this.storageDirForUser(user);
297
279
  const { startObjProcs, syncedStore } = await storage_1.SyncedStore.makeAndStart((0, path_1.join)(storageDir, SYNCED_STORAGE_DIR), user, getSigner, this.storageGetterForSyncedStorage, this.cryptor, () => resolver(user), makeNet(), logError);
298
- // getting parameters records them locally on a disk
299
- const params = await getRootKeyDerivParams(storageDir, syncedStore.getRootKeyDerivParamsFromServer);
300
- const key = ((typeof keyOrGen === 'function') ?
301
- await keyOrGen(params) : keyOrGen);
302
- this.synced = await StorageAndFS.newOrExisting(syncedStore, key);
303
- this.local = await StorageAndFS.newOrExisting(await storage_2.LocalStorage.makeAndStart((0, path_1.join)(storageDir, LOCAL_STORAGE_DIR), this.storageGetterForLocalStorage, this.cryptor, logError), key);
280
+ this.synced = await StorageAndFS.makeNew(syncedStore, key);
281
+ this.local = await StorageAndFS.makeNew(await storage_2.LocalStorage.makeAndStart((0, path_1.join)(storageDir, LOCAL_STORAGE_DIR), this.storageGetterForLocalStorage, this.cryptor, logError), key);
304
282
  key.fill(0);
283
+ await saveRootKeyDerivParamsToDisk(storageDir, params);
305
284
  startObjProcs();
306
285
  return (!!this.synced && !!this.local);
307
286
  }
@@ -523,7 +502,7 @@ async function applyPolicyToFSCollection(c, policy, path) {
523
502
  }
524
503
  const nameAndItem = await (0, async_iter_1.asyncFind)(await c.entries(), async (v) => path.startsWith(v[0]));
525
504
  if (!nameAndItem) {
526
- throw (0, file_1.makeFileException)(file_1.Code.notFound, path);
505
+ throw (0, file_1.makeFileException)('notFound', path);
527
506
  }
528
507
  const [name, item] = nameAndItem;
529
508
  path = path.substring(name.length);
@@ -9,7 +9,7 @@ export declare class LocalStorage implements Storage {
9
9
  private readonly files;
10
10
  private readonly getStorages;
11
11
  readonly cryptor: AsyncSBoxCryptor;
12
- private readonly logError;
12
+ readonly logError: LogError;
13
13
  readonly type = "local";
14
14
  readonly versioned = true;
15
15
  readonly nodes: NodesContainer;
@@ -1,10 +1,8 @@
1
1
  import { SynchronizerOnObjId, SyncedObj } from './obj-files';
2
- import { StorageOwner as RemoteStorage } from '../../../lib-client/3nstorage/service';
3
2
  export declare class GC {
4
3
  private readonly sync;
5
4
  private readonly rmObjFromCache;
6
5
  private readonly rmObjFolder;
7
- private readonly remote;
8
6
  private isStopped;
9
7
  /**
10
8
  * All gc steps are done in this process.
@@ -20,11 +18,10 @@ export declare class GC {
20
18
  * with wip set.
21
19
  */
22
20
  private scheduled;
23
- constructor(sync: SynchronizerOnObjId, rmObjFromCache: (obj: SyncedObj) => void, rmObjFolder: (objId: string) => Promise<void>, remote: RemoteStorage);
21
+ constructor(sync: SynchronizerOnObjId, rmObjFromCache: (obj: SyncedObj) => void, rmObjFolder: (objId: string) => Promise<void>);
24
22
  scheduleCollection: (obj: SyncedObj) => void;
25
23
  stop(): Promise<void>;
26
24
  private objCollecting;
27
25
  private collectIn;
28
- private upsyncObjRemovalWhenNeeded;
29
26
  private checkAndRemoveWholeObjFolder;
30
27
  }
@@ -24,11 +24,10 @@ const path_1 = require("path");
24
24
  const utils_1 = require("../common/utils");
25
25
  const upload_header_file_1 = require("./upload-header-file");
26
26
  class GC {
27
- constructor(sync, rmObjFromCache, rmObjFolder, remote) {
27
+ constructor(sync, rmObjFromCache, rmObjFolder) {
28
28
  this.sync = sync;
29
29
  this.rmObjFromCache = rmObjFromCache;
30
30
  this.rmObjFolder = rmObjFolder;
31
- this.remote = remote;
32
31
  this.isStopped = false;
33
32
  /**
34
33
  * All gc steps are done in this process.
@@ -71,27 +70,11 @@ class GC {
71
70
  this.isStopped = true;
72
71
  }
73
72
  async collectIn(obj) {
74
- if (obj.statusObj().isArchived()) {
75
- await this.upsyncObjRemovalWhenNeeded(obj);
76
- }
77
73
  const nonGarbage = obj.statusObj().getNonGarbageVersions();
78
74
  if (!(await this.checkAndRemoveWholeObjFolder(obj, nonGarbage))) {
79
75
  await removeGarbageFiles(obj, nonGarbage);
80
76
  }
81
77
  }
82
- async upsyncObjRemovalWhenNeeded(obj) {
83
- if (!needsUpsyncOfRemoval(obj)) {
84
- return;
85
- }
86
- try {
87
- await this.remote.deleteObj(obj.objId);
88
- }
89
- catch (exc) {
90
- // XXX will need to schedule other attempt to delete on remote
91
- return;
92
- }
93
- await obj.statusObj().recordSyncOfObjRemoval();
94
- }
95
78
  async checkAndRemoveWholeObjFolder(obj, { local, remote }) {
96
79
  if (obj.objId
97
80
  && obj.statusObj().isArchived()
@@ -13,6 +13,12 @@ import { StorageOwner as RemoteStorage } from '../../../lib-client/3nstorage/ser
13
13
  import { UploadHeaderChange } from '../../../lib-client/3nstorage/xsp-fs/common';
14
14
  export declare const UNSYNCED_FILE_NAME_EXT = "unsynced";
15
15
  export declare const REMOTE_FILE_NAME_EXT = "v";
16
+ /**
17
+ * File system has nodes. Each node may have data in one or many objects of
18
+ * storage. SyncedObj allows to work with files of storage object, even when
19
+ * file system node no longer exists. ObjFiles is a holder and factory of
20
+ * SyncedObj's.
21
+ */
16
22
  export declare class ObjFiles {
17
23
  private readonly folders;
18
24
  private readonly logError;
@@ -22,6 +28,7 @@ export declare class ObjFiles {
22
28
  private readonly gc;
23
29
  private constructor();
24
30
  static makeFor(path: string, remote: RemoteStorage, logError: LogError): Promise<ObjFiles>;
31
+ private canMoveObjToDeeperCache;
25
32
  findObj(objId: ObjId): Promise<SyncedObj | undefined>;
26
33
  getObjInCache(objId: ObjId): SyncedObj | undefined;
27
34
  private makeObj;
@@ -31,7 +38,7 @@ export declare class ObjFiles {
31
38
  fileWrite$: Observable<FileWrite[]>;
32
39
  newObj: SyncedObj;
33
40
  }>;
34
- findUnsyncedObjs(): Observable<ObjId>;
41
+ findObjsToRemoveOnRemote(): Observable<ObjId>;
35
42
  scheduleGC(obj: SyncedObj): void;
36
43
  }
37
44
  export declare type SynchronizerOnObjId = <T>(objId: ObjId, action: () => Promise<T>) => Promise<T>;
@@ -81,4 +88,5 @@ export declare class SyncedObj {
81
88
  }>;
82
89
  syncStatus(): SyncedObjStatus;
83
90
  statusObj(): ObjStatus;
91
+ recordRemovalUploadAndGC(): Promise<void>;
84
92
  }
@@ -19,7 +19,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
19
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
21
  const synced_1 = require("../../../lib-common/processes/synced");
22
- const sleep_1 = require("../../../lib-common/processes/sleep");
23
22
  const obj_folders_1 = require("../../../lib-client/objs-on-disk/obj-folders");
24
23
  const fs = require("../../../lib-common/async-fs-node");
25
24
  const obj_on_disk_1 = require("../../../lib-client/objs-on-disk/obj-on-disk");
@@ -35,6 +34,12 @@ const upload_header_file_1 = require("./upload-header-file");
35
34
  const utils_1 = require("../common/utils");
36
35
  exports.UNSYNCED_FILE_NAME_EXT = 'unsynced';
37
36
  exports.REMOTE_FILE_NAME_EXT = 'v';
37
+ /**
38
+ * File system has nodes. Each node may have data in one or many objects of
39
+ * storage. SyncedObj allows to work with files of storage object, even when
40
+ * file system node no longer exists. ObjFiles is a holder and factory of
41
+ * SyncedObj's.
42
+ */
38
43
  class ObjFiles {
39
44
  constructor(folders, remote, logError) {
40
45
  this.folders = folders;
@@ -46,31 +51,32 @@ class ObjFiles {
46
51
  if (this.objs.get(obj.objId) === obj) {
47
52
  this.objs.delete(obj.objId);
48
53
  }
49
- }, objId => this.folders.removeFolderOf(objId), remote);
54
+ }, objId => this.folders.removeFolderOf(objId));
50
55
  Object.freeze(this);
51
56
  }
52
57
  static async makeFor(path, remote, logError) {
53
- const canMove = async (objId, objFolderPath) => {
54
- if (objFiles.objs.has(objId)) {
55
- return false;
56
- }
57
- const lst = await fs.readdir(objFolderPath);
58
- for (const fName of lst) {
59
- if (fName.endsWith(exports.UNSYNCED_FILE_NAME_EXT)) {
60
- return false;
61
- }
62
- }
63
- try {
64
- return (await obj_status_1.ObjStatus.fileShowsObjNotInSyncedState(objFolderPath, objId));
65
- }
66
- catch (exc) {
67
- return false;
68
- }
69
- };
58
+ const canMove = (objId, objFolderPath) => objFiles.canMoveObjToDeeperCache(objId, objFolderPath);
70
59
  const folders = await obj_folders_1.ObjFolders.makeWithGenerations(path, canMove, logError);
71
60
  const objFiles = new ObjFiles(folders, remote, logError);
72
61
  return objFiles;
73
62
  }
63
+ async canMoveObjToDeeperCache(objId, objFolderPath) {
64
+ if (this.objs.has(objId)) {
65
+ return false;
66
+ }
67
+ const lst = await fs.readdir(objFolderPath);
68
+ for (const fName of lst) {
69
+ if (fName.endsWith(exports.UNSYNCED_FILE_NAME_EXT)) {
70
+ return false;
71
+ }
72
+ }
73
+ try {
74
+ return (await obj_status_1.ObjStatus.fileShowsObjNotInSyncedState(objFolderPath, objId));
75
+ }
76
+ catch (exc) {
77
+ return false;
78
+ }
79
+ }
74
80
  async findObj(objId) {
75
81
  let obj = this.objs.get(objId);
76
82
  if (obj) {
@@ -131,25 +137,23 @@ class ObjFiles {
131
137
  .pipe((0, utils_for_observables_1.flatTap)(undefined, err => this.removeFailedNewObj(newObj)));
132
138
  return { fileWrite$, newObj };
133
139
  }
134
- findUnsyncedObjs() {
140
+ findObjsToRemoveOnRemote() {
135
141
  return (0, rxjs_1.from)([undefined])
136
142
  .pipe(
137
143
  // listing recent folders, exactly once
138
144
  (0, operators_1.mergeMap)(() => this.folders.listRecent()),
139
145
  // flatten array and space it in time, to process folders one by one
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);
142
- return objsAndPaths;
143
- }, 1),
144
- // check, emiting objId, if not synced, and undefined, if synced
145
- (0, operators_1.mergeMap)(({ path, objId }) => this.sync(objId, async () => {
146
- if (this.objs.has(objId)) {
147
- return;
146
+ (0, operators_1.mergeMap)(objsAndPaths => objsAndPaths), (0, operators_1.mergeMap)(async ({ objId, path }) => {
147
+ const obj = this.objs.get(objId);
148
+ if (obj) {
149
+ return (obj.statusObj().needsRemovalOnRemote() ?
150
+ objId : undefined);
151
+ }
152
+ else {
153
+ const needsRm = await obj_status_1.ObjStatus.fileShowsObjNeedsRemovalOnRemote(path, objId);
154
+ return (needsRm ? objId : undefined);
148
155
  }
149
- const notSynced = await obj_status_1.ObjStatus.fileShowsObjNotInSyncedState(path, objId)
150
- .catch(notFoundOrReThrow).catch(this.logError);
151
- return (notSynced ? objId : undefined);
152
- })), (0, operators_1.filter)(objId => (objId !== undefined)));
156
+ }, 1), (0, operators_1.filter)(objId => (objId !== undefined)));
153
157
  }
154
158
  scheduleGC(obj) {
155
159
  this.gc.scheduleCollection(obj);
@@ -336,7 +340,7 @@ class SyncedObj {
336
340
  else {
337
341
  await fs.rename(this.localVerPath(localVersion), remotePath);
338
342
  }
339
- await this.status.markLocalVersionSynced(localVersion, uploadVersion);
343
+ await this.status.recordUploadCompletion(localVersion, uploadVersion);
340
344
  this.scheduleSelfGC();
341
345
  }
342
346
  dropCachedLocalObjVersionsLessOrEqual(version) {
@@ -387,6 +391,10 @@ class SyncedObj {
387
391
  statusObj() {
388
392
  return this.status;
389
393
  }
394
+ async recordRemovalUploadAndGC() {
395
+ await this.status.recordRemoteRemovalCompletion();
396
+ this.scheduleSelfGC();
397
+ }
390
398
  }
391
399
  exports.SyncedObj = SyncedObj;
392
400
  Object.freeze(SyncedObj.prototype);
@@ -18,11 +18,11 @@ export interface ObjStatusInfo {
18
18
  local?: LocalVersions;
19
19
  synced?: SyncMarker;
20
20
  remote: VersionsOnServer;
21
+ upload?: UploadInfo;
21
22
  }
22
23
  export interface LocalVersions extends VersionsInfo {
23
24
  isArchived?: boolean;
24
25
  archived?: undefined;
25
- upload?: UploadInfo;
26
26
  }
27
27
  export interface SyncMarker {
28
28
  version?: number;
@@ -32,12 +32,19 @@ export interface SyncMarker {
32
32
  export interface VersionsOnServer extends VersionsInfo {
33
33
  isArchived?: boolean;
34
34
  }
35
- export interface UploadInfo {
35
+ export declare type UploadInfo = NewVersionUpload | RemovalUpload;
36
+ export interface NewVersionUpload {
37
+ type: 'new-version';
36
38
  localVersion: number;
37
39
  uploadVersion: number;
38
40
  baseVersion?: number;
39
41
  needUpload?: WholeVerOrderedUpload | DiffVerOrderedUpload;
40
42
  }
43
+ export interface RemovalUpload {
44
+ type: 'removal';
45
+ isPostponed: boolean;
46
+ localVersion?: number;
47
+ }
41
48
  export interface WholeVerOrderedUpload {
42
49
  type: 'ordered-whole';
43
50
  createObj?: boolean;
@@ -74,20 +81,24 @@ export declare class ObjStatus implements SyncedObjStatus, UploadStatusRecorder
74
81
  static makeNew(objFolder: string, objId: ObjId, logError: LogError): Promise<ObjStatus>;
75
82
  static makeForDownloadedVersion(objFolder: string, objId: ObjId, version: number, currentRemote: number, logError: LogError): Promise<ObjStatus>;
76
83
  static fileShowsObjNotInSyncedState(objFolder: string, objId: ObjId): Promise<boolean>;
84
+ static fileShowsObjNeedsRemovalOnRemote(objFolder: string, objId: ObjId): Promise<boolean>;
85
+ needsRemovalOnRemote(): boolean;
86
+ clearPostponeFlagInRemovalOnRemote(): Promise<boolean>;
77
87
  private updateStateIndicator;
78
88
  isArchived(): boolean;
79
89
  getCurrentLocalOrSynced(): number;
80
90
  getNonGarbageVersions(): NonGarbage;
81
91
  removeCurrentVersion(): Promise<void>;
82
92
  private triggerSaveProc;
83
- recordUploadStart(info: UploadInfo): Promise<void>;
84
- recordUploadInterimState(info: UploadInfo): Promise<void>;
85
- recordUploadCancellation(info: UploadInfo): Promise<void>;
93
+ recordUploadStart(info: NewVersionUpload): Promise<void>;
94
+ recordUploadInterimState(info: NewVersionUpload): Promise<void>;
95
+ recordUploadCancellation(info: NewVersionUpload): Promise<void>;
96
+ recordUploadCompletion(localVersion: number, uploadVersion: number): Promise<void>;
86
97
  recordArchVersionRemoval(version: number): Promise<void>;
87
98
  recordVersionArchival(version: number): Promise<void>;
88
99
  recordRemoteRemoval(): Promise<void>;
100
+ recordRemoteRemovalCompletion(): Promise<void>;
89
101
  recordRemoteChange(version: number): Promise<void>;
90
- recordSyncOfObjRemoval(): Promise<void>;
91
102
  recordStatusFromServer({ archived, current }: RemoteObjStatus): Promise<void>;
92
103
  /**
93
104
  * When given object version is a diff on some base, this method returns
@@ -102,7 +113,6 @@ export declare class ObjStatus implements SyncedObjStatus, UploadStatusRecorder
102
113
  localBases?: number[];
103
114
  syncedBase?: number;
104
115
  } | undefined;
105
- markLocalVersionSynced(localVersion: number, uploadVersion: number): Promise<void>;
106
116
  setLocalCurrentVersion(version: number, baseVer: number | undefined): Promise<void>;
107
117
  listVersions(): {
108
118
  current?: number;
@@ -113,6 +123,7 @@ export declare class ObjStatus implements SyncedObjStatus, UploadStatusRecorder
113
123
  latestSyncedVersion(): number | undefined;
114
124
  syncStatus(): SyncStatus;
115
125
  neverUploaded(): boolean;
126
+ versionBeforeUnsyncedRemoval(): number | undefined;
116
127
  adoptRemoteVersion(version?: number, dropLocalVer?: boolean): Promise<void>;
117
128
  }
118
129
  export declare function readAndCheckStatus(objFolder: string, objId: ObjId): Promise<ObjStatusInfo>;