core-3nweb-client-lib 0.43.8 → 0.43.9

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 (34) hide show
  1. package/build/api-defs/files.d.ts +68 -4
  2. package/build/core/storage/synced/obj-files.d.ts +1 -0
  3. package/build/core/storage/synced/obj-files.js +16 -0
  4. package/build/core/storage/synced/obj-status.d.ts +1 -0
  5. package/build/core/storage/synced/obj-status.js +18 -0
  6. package/build/core/storage/synced/storage.d.ts +6 -2
  7. package/build/core/storage/synced/storage.js +12 -17
  8. package/build/core/storage/synced/upsyncer.d.ts +10 -1
  9. package/build/core/storage/synced/upsyncer.js +72 -9
  10. package/build/core-ipc/file.d.ts +23 -4
  11. package/build/core-ipc/file.js +56 -80
  12. package/build/core-ipc/fs.js +46 -132
  13. package/build/lib-client/fs-utils/files.js +2 -0
  14. package/build/lib-client/objs-on-disk/obj-on-disk.d.ts +1 -0
  15. package/build/lib-client/objs-on-disk/obj-on-disk.js +8 -1
  16. package/build/lib-client/xsp-fs/common.d.ts +13 -21
  17. package/build/lib-client/xsp-fs/common.js +4 -16
  18. package/build/lib-client/xsp-fs/file-node.js +9 -22
  19. package/build/lib-client/xsp-fs/file.d.ts +4 -0
  20. package/build/lib-client/xsp-fs/file.js +18 -1
  21. package/build/lib-client/xsp-fs/folder-node.d.ts +5 -1
  22. package/build/lib-client/xsp-fs/folder-node.js +15 -27
  23. package/build/lib-client/xsp-fs/fs.d.ts +4 -0
  24. package/build/lib-client/xsp-fs/fs.js +25 -1
  25. package/build/lib-client/xsp-fs/link-node.js +3 -19
  26. package/build/lib-client/xsp-fs/node-in-fs.d.ts +18 -5
  27. package/build/lib-client/xsp-fs/node-in-fs.js +70 -12
  28. package/build/lib-common/processes/labelled-exec-pools.js +1 -3
  29. package/build/protos/asmail.proto.js +1436 -1437
  30. package/build/protos/file.proto.js +1077 -387
  31. package/build/protos/fs.proto.js +1395 -1396
  32. package/package.json +4 -4
  33. package/protos/file.proto +24 -12
  34. package/protos/fs.proto +8 -21
@@ -127,29 +127,16 @@ class FileNode extends node_in_fs_1.NodeInFS {
127
127
  super.setUpdatedParams(version, fileAttrs.attrs, fileAttrs.xattrs);
128
128
  }
129
129
  async getStats(flags) {
130
- let attrs;
131
- let version;
132
- let size;
133
- if ((0, node_in_fs_1.shouldReadCurrentVersion)(flags)) {
134
- attrs = this.attrs;
135
- version = this.version;
136
- size = this.fileSize;
137
- }
138
- else {
139
- const src = await this.getObjSrcOfVersion(flags);
140
- const fileAttrs = await this.crypto.getFileAttrs(src);
141
- attrs = fileAttrs.attrs;
142
- version = src.version;
143
- size = fileAttrs.size;
130
+ const { stats, attrs } = await this.getStatsAndSize(flags);
131
+ stats.size = (attrs ? attrs.size : this.fileSize);
132
+ if ((this.storage.type === 'synced')
133
+ || (this.storage.type === 'share')) {
134
+ const bytesNeedDownload = await this.syncedStorage().getNumOfBytesNeedingDownload(this.objId, stats.version);
135
+ if (typeof bytesNeedDownload === 'number') {
136
+ stats.bytesNeedDownload = bytesNeedDownload;
137
+ }
144
138
  }
145
- return {
146
- ctime: new Date(attrs.ctime),
147
- mtime: new Date(attrs.mtime),
148
- version,
149
- writable: false,
150
- isFile: true,
151
- size
152
- };
139
+ return stats;
153
140
  }
154
141
  async readSrc(flags) {
155
142
  const objSrc = await this.getObjSrcOfVersion(flags);
@@ -98,6 +98,10 @@ declare class V implements WritableFileVersionedAPI, N {
98
98
  declare class S implements WritableFileSyncAPI {
99
99
  private readonly n;
100
100
  constructor(n: N);
101
+ startUpload(opts?: OptionsToUploadLocal): Promise<{
102
+ uploadVersion: number;
103
+ uploadTaskId: number;
104
+ } | undefined>;
101
105
  upload(opts?: OptionsToUploadLocal): Promise<number | undefined>;
102
106
  status(skipServerCheck?: boolean): Promise<SyncStatus>;
103
107
  updateStatusInfo(): Promise<SyncStatus>;
@@ -224,10 +224,27 @@ class S {
224
224
  this.n = n;
225
225
  Object.freeze(this);
226
226
  }
227
+ async startUpload(opts) {
228
+ this.n.ensureIsWritable();
229
+ const node = await this.n.getNode();
230
+ const startedUpload = await node.startUpload(opts);
231
+ if (startedUpload) {
232
+ const { uploadTaskId, uploadVersion } = startedUpload;
233
+ return { uploadTaskId, uploadVersion };
234
+ }
235
+ else {
236
+ return;
237
+ }
238
+ }
227
239
  async upload(opts) {
228
240
  this.n.ensureIsWritable();
229
241
  const node = await this.n.getNode();
230
- const uploadVersion = await node.upload(opts);
242
+ const startedUpload = await node.startUpload(opts);
243
+ if (!startedUpload) {
244
+ return;
245
+ }
246
+ const { uploadVersion, completion } = startedUpload;
247
+ await completion;
231
248
  return uploadVersion;
232
249
  }
233
250
  async status(skipServerCheck = false) {
@@ -144,7 +144,11 @@ export declare class FolderNode extends NodeInFS<FolderPersistance> {
144
144
  private removeChildrenObjsInSyncedStorage;
145
145
  private uploadRemovalOfObjs;
146
146
  getParamsForLink(): LinkParameters<FolderLinkParams>;
147
- upload(opts: OptionsToUploadLocal | undefined): Promise<number | undefined>;
147
+ startUpload(opts: OptionsToUploadLocal | undefined): Promise<{
148
+ uploadVersion: number;
149
+ completion: Promise<void>;
150
+ uploadTaskId: number;
151
+ } | undefined>;
148
152
  private uploadRemovalOf;
149
153
  private listRemovedInTreeToUploadRm;
150
154
  protected needUpload(opts: OptionsToUploadLocal | undefined): Promise<{
@@ -163,24 +163,8 @@ class FolderNode extends node_in_fs_1.NodeInFS {
163
163
  return rf;
164
164
  }
165
165
  async getStats(flags) {
166
- let attrs;
167
- let version;
168
- if ((0, node_in_fs_1.shouldReadCurrentVersion)(flags)) {
169
- attrs = this.attrs;
170
- version = this.version;
171
- }
172
- else {
173
- const src = await this.getObjSrcOfVersion(flags);
174
- attrs = await this.crypto.getAttrs(src);
175
- version = src.version;
176
- }
177
- return {
178
- ctime: new Date(attrs.ctime),
179
- mtime: new Date(attrs.mtime),
180
- version,
181
- writable: false,
182
- isFolder: true,
183
- };
166
+ const { stats } = await this.getStatsAndSize(flags);
167
+ return stats;
184
168
  }
185
169
  async setCurrentStateFrom(src) {
186
170
  const { folderInfo, attrs, xattrs } = await this.crypto.read(src);
@@ -801,26 +785,30 @@ class FolderNode extends node_in_fs_1.NodeInFS {
801
785
  };
802
786
  return linkParams;
803
787
  }
804
- async upload(opts) {
788
+ async startUpload(opts) {
805
789
  try {
806
790
  const toUpload = await this.needUpload(opts);
807
791
  if (!toUpload) {
808
792
  return;
809
793
  }
794
+ const { localVersion, createOnRemote, uploadVersion } = toUpload;
810
795
  if (toUpload.createOnRemote) {
811
- return await super.upload(opts);
796
+ return await this.startUploadProcess(localVersion, createOnRemote, uploadVersion);
812
797
  }
813
- const storage = this.syncedStorage();
814
- const { localVersion, uploadVersion } = toUpload;
815
798
  const removedNodes = await this.getNodesRemovedBetweenVersions(localVersion, uploadVersion - 1);
816
- const uploadHeader = await this.uploadHeaderChange(localVersion, uploadVersion);
817
- await storage.upload(this.objId, localVersion, uploadVersion, uploadHeader, false);
799
+ const { completion, uploadTaskId } = await this.startUploadProcess(localVersion, createOnRemote, uploadVersion);
818
800
  if (removedNodes.length > 0) {
819
801
  // start upload of children's removal after folder's upload;
820
- // we also don't await for chidren removal
821
- this.uploadRemovalOf(removedNodes);
802
+ // we also don't await for chidren removal in returned completion
803
+ completion.then(() => this.uploadRemovalOf(removedNodes));
822
804
  }
823
- return uploadVersion;
805
+ return {
806
+ completion: completion.catch(exc => {
807
+ throw (0, common_1.setPathInExc)(exc, this.name);
808
+ }),
809
+ uploadTaskId,
810
+ uploadVersion
811
+ };
824
812
  }
825
813
  catch (exc) {
826
814
  throw (0, common_1.setPathInExc)(exc, this.name);
@@ -162,6 +162,10 @@ declare class V implements WritableFSVersionedAPI, N {
162
162
  declare class S implements WritableFSSyncAPI {
163
163
  private readonly n;
164
164
  constructor(n: N);
165
+ startUpload(path: string, opts?: OptionsToUploadLocal): Promise<{
166
+ uploadVersion: number;
167
+ uploadTaskId: number;
168
+ } | undefined>;
165
169
  upload(path: string, opts?: OptionsToUploadLocal): Promise<number | undefined>;
166
170
  status(path: string, skipServerCheck?: boolean): Promise<SyncStatus>;
167
171
  updateStatusInfo(path: string): Promise<SyncStatus>;
@@ -706,11 +706,35 @@ class S {
706
706
  this.n = n;
707
707
  Object.freeze(this);
708
708
  }
709
+ async startUpload(path, opts) {
710
+ this.n.ensureIsWritable();
711
+ const node = await this.n.get(path);
712
+ try {
713
+ const startedUpload = await node.startUpload(opts);
714
+ if (startedUpload) {
715
+ const { uploadTaskId, uploadVersion } = startedUpload;
716
+ return { uploadTaskId, uploadVersion };
717
+ }
718
+ else {
719
+ return;
720
+ }
721
+ }
722
+ catch (exc) {
723
+ throw (0, common_1.setPathInExc)(exc, path);
724
+ }
725
+ ;
726
+ }
709
727
  async upload(path, opts) {
710
728
  this.n.ensureIsWritable();
711
729
  const node = await this.n.get(path);
712
730
  try {
713
- return await node.upload(opts);
731
+ const startedUpload = await node.startUpload(opts);
732
+ if (!startedUpload) {
733
+ return;
734
+ }
735
+ const { completion, uploadVersion } = startedUpload;
736
+ await completion;
737
+ return uploadVersion;
714
738
  }
715
739
  catch (exc) {
716
740
  throw (0, common_1.setPathInExc)(exc, path);
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /*
3
- Copyright (C) 2016 - 2018, 2020, 2022 3NSoft Inc.
3
+ Copyright (C) 2016 - 2018, 2020, 2022, 2025 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
@@ -104,24 +104,8 @@ class LinkNode extends node_in_fs_1.NodeInFS {
104
104
  this.setUpdatedState(params, src.version, attrs, xattrs);
105
105
  }
106
106
  async getStats(flags) {
107
- let attrs;
108
- let version;
109
- if ((0, node_in_fs_1.shouldReadCurrentVersion)(flags)) {
110
- attrs = this.attrs;
111
- version = this.version;
112
- }
113
- else {
114
- const src = await this.getObjSrcOfVersion(flags);
115
- attrs = await this.crypto.getAttrs(src);
116
- version = src.version;
117
- }
118
- return {
119
- ctime: new Date(attrs.ctime),
120
- mtime: new Date(attrs.mtime),
121
- version,
122
- writable: false,
123
- isLink: true,
124
- };
107
+ const { stats } = await this.getStatsAndSize(flags);
108
+ return stats;
125
109
  }
126
110
  setUpdatedState(params, version, attrs, xattrs) {
127
111
  this.linkParams = params;
@@ -1,9 +1,9 @@
1
- import { FSChangeSrc, Node, NodeType, Storage, SyncedStorage, UploadHeaderChange } from './common';
1
+ import { FSChangeSrc, Node, NodeType, Storage, SyncedStorage } from './common';
2
2
  import { Observable } from 'rxjs';
3
3
  import { CommonAttrs, XAttrs } from './attrs';
4
- import { NodePersistance } from './node-persistence';
4
+ import { Attrs, NodePersistance } from './node-persistence';
5
5
  import { ObjSource } from 'xsp-files';
6
- export type FSEvent = web3n.files.FolderEvent | web3n.files.FileEvent;
6
+ export type FSEvent = web3n.files.FolderEvent | web3n.files.FileEvent | web3n.files.UploadEvent;
7
7
  type RemoteEvent = web3n.files.RemoteEvent;
8
8
  type XAttrsChanges = web3n.files.XAttrsChanges;
9
9
  type SyncStatus = web3n.files.SyncStatus;
@@ -46,6 +46,10 @@ export declare abstract class NodeInFS<P extends NodePersistance> implements Nod
46
46
  version: number;
47
47
  }>;
48
48
  abstract getStats(flags?: VersionedReadFlags): Promise<Stats>;
49
+ protected getStatsAndSize(flags?: VersionedReadFlags): Promise<{
50
+ stats: Stats;
51
+ attrs?: Attrs;
52
+ }>;
49
53
  listVersions(): Promise<{
50
54
  current?: number;
51
55
  archived?: number[];
@@ -85,8 +89,17 @@ export declare abstract class NodeInFS<P extends NodePersistance> implements Nod
85
89
  uploadVersion: number;
86
90
  createOnRemote: boolean;
87
91
  } | undefined>;
88
- upload(opts: OptionsToUploadLocal | undefined): Promise<number | undefined>;
89
- protected uploadHeaderChange(localVersion: number, uploadVersion: number): Promise<UploadHeaderChange | undefined>;
92
+ startUpload(opts: OptionsToUploadLocal | undefined): Promise<{
93
+ uploadVersion: number;
94
+ completion: Promise<void>;
95
+ uploadTaskId: number;
96
+ } | undefined>;
97
+ protected startUploadProcess(localVersion: number, createOnRemote: boolean, uploadVersion: number): Promise<{
98
+ uploadVersion: number;
99
+ completion: Promise<void>;
100
+ uploadTaskId: number;
101
+ }>;
102
+ private makeHeaderForUploadIfVersionChanges;
90
103
  }
91
104
  export declare function shouldReadCurrentVersion(flags: VersionedReadFlags | undefined): boolean;
92
105
  export {};
@@ -145,6 +145,54 @@ class NodeInFS {
145
145
  };
146
146
  }
147
147
  }
148
+ async getStatsAndSize(flags) {
149
+ var _a;
150
+ let attrs;
151
+ let version;
152
+ if (shouldReadCurrentVersion(flags)) {
153
+ attrs = this.attrs;
154
+ version = this.version;
155
+ }
156
+ else {
157
+ const src = await this.getObjSrcOfVersion(flags);
158
+ attrs = await this.crypto.getAttrs(src);
159
+ version = src.version;
160
+ }
161
+ const stats = {
162
+ ctime: new Date(attrs.ctime),
163
+ mtime: new Date(attrs.mtime),
164
+ version,
165
+ writable: false,
166
+ };
167
+ switch (this.type) {
168
+ case 'folder':
169
+ stats.isFolder = true;
170
+ break;
171
+ case 'link':
172
+ stats.isLink = true;
173
+ break;
174
+ case 'file':
175
+ stats.isFile = true;
176
+ break;
177
+ }
178
+ if ((this.storage.type === 'synced')
179
+ || (this.storage.type === 'share')) {
180
+ const syncStatus = await this.syncedStorage().status(this.objId);
181
+ const { synced } = syncStatus.syncStatus();
182
+ if (synced) {
183
+ if (synced.latest && (version > synced.latest)) {
184
+ stats.versionSyncBranch = (((flags === null || flags === void 0 ? void 0 : flags.remoteVersion) === version) ? 'remote' : 'local');
185
+ }
186
+ else if ((version === synced.latest) || ((_a = synced.archived) === null || _a === void 0 ? void 0 : _a.includes(version))) {
187
+ stats.versionSyncBranch = 'synced';
188
+ }
189
+ }
190
+ else {
191
+ stats.versionSyncBranch = (((flags === null || flags === void 0 ? void 0 : flags.remoteVersion) === version) ? 'remote' : 'local');
192
+ }
193
+ }
194
+ return { stats, attrs: (attrs.pack ? undefined : attrs) };
195
+ }
148
196
  async listVersions() {
149
197
  return (await this.storage.status(this.objId)).listVersions();
150
198
  }
@@ -429,29 +477,39 @@ class NodeInFS {
429
477
  }
430
478
  return { createOnRemote: (uploadVersion === 1), localVersion, uploadVersion };
431
479
  }
432
- async upload(opts) {
480
+ async startUpload(opts) {
433
481
  try {
434
482
  const toUpload = await this.needUpload(opts);
435
483
  if (!toUpload) {
436
484
  return;
437
485
  }
438
486
  const { localVersion, createOnRemote, uploadVersion } = toUpload;
439
- const uploadHeader = await this.uploadHeaderChange(localVersion, uploadVersion);
440
- const storage = this.syncedStorage();
441
- await storage.upload(this.objId, localVersion, uploadVersion, uploadHeader, createOnRemote);
442
- return await this.doChange(true, async () => {
443
- storage.dropCachedLocalObjVersionsLessOrEqual(this.objId, localVersion);
444
- if (this.currentVersion === localVersion) {
445
- this.currentVersion = uploadVersion;
446
- }
447
- return uploadVersion;
448
- });
487
+ return await this.startUploadProcess(localVersion, createOnRemote, uploadVersion);
449
488
  }
450
489
  catch (exc) {
451
490
  throw (0, common_1.setPathInExc)(exc, this.name);
452
491
  }
453
492
  }
454
- async uploadHeaderChange(localVersion, uploadVersion) {
493
+ async startUploadProcess(localVersion, createOnRemote, uploadVersion) {
494
+ const uploadHeader = await this.makeHeaderForUploadIfVersionChanges(localVersion, uploadVersion);
495
+ const storage = this.syncedStorage();
496
+ const { completion, uploadTaskId } = await storage.startUpload(this.objId, localVersion, uploadVersion, uploadHeader, createOnRemote, event => {
497
+ event.path = this.name;
498
+ this.broadcastEvent(event);
499
+ });
500
+ return {
501
+ completion: completion.then(() => this.doChange(true, async () => {
502
+ if (this.currentVersion === localVersion) {
503
+ this.currentVersion = uploadVersion;
504
+ }
505
+ })).catch(exc => {
506
+ throw (0, common_1.setPathInExc)(exc, this.name);
507
+ }),
508
+ uploadTaskId,
509
+ uploadVersion
510
+ };
511
+ }
512
+ async makeHeaderForUploadIfVersionChanges(localVersion, uploadVersion) {
455
513
  if (localVersion === uploadVersion) {
456
514
  return;
457
515
  }
@@ -60,9 +60,7 @@ class ProcessingPool {
60
60
  await this.doOnError(err);
61
61
  }
62
62
  finally {
63
- if (proc) {
64
- this.inProcess.delete(proc);
65
- }
63
+ this.inProcess.delete(proc);
66
64
  }
67
65
  return this.processNextQueued();
68
66
  }