core-3nweb-client-lib 0.44.6 → 0.44.8

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 (43) hide show
  1. package/build/api-defs/files.d.ts +1 -0
  2. package/build/api-defs/web3n.d.ts +2 -1
  3. package/build/core/asmail/inbox/inbox-events.d.ts +0 -1
  4. package/build/core/asmail/inbox/inbox-events.js +3 -5
  5. package/build/core/asmail/inbox/index.js +1 -1
  6. package/build/core/asmail/inbox/msg-downloader.d.ts +1 -2
  7. package/build/core/asmail/inbox/msg-downloader.js +3 -4
  8. package/build/core/storage/synced/obj-files.js +1 -1
  9. package/build/core/storage/synced/obj-status.d.ts +2 -0
  10. package/build/core/storage/synced/obj-status.js +9 -5
  11. package/build/core/storage/synced/remote-events.d.ts +0 -1
  12. package/build/core/storage/synced/remote-events.js +5 -7
  13. package/build/core/storage/synced/storage.js +2 -2
  14. package/build/core/storage/synced/upsyncer.d.ts +1 -2
  15. package/build/core/storage/synced/upsyncer.js +49 -25
  16. package/build/lib-client/3nstorage/storage-owner.js +1 -1
  17. package/build/lib-client/asmail/recipient.js +8 -4
  18. package/build/lib-client/cryptor/cryptor-wasm.js +1 -1
  19. package/build/lib-client/cryptor/cryptor.wasm +0 -0
  20. package/build/lib-client/cryptor/worker-js.js +4 -2
  21. package/build/lib-client/local-files/dev-file-sink.js +30 -28
  22. package/build/lib-client/local-files/dev-file-src.js +7 -6
  23. package/build/lib-client/local-files/device-fs.js +23 -23
  24. package/build/lib-client/objs-on-disk/obj-folders.js +6 -3
  25. package/build/lib-client/request-utils.d.ts +2 -1
  26. package/build/lib-client/request-utils.js +8 -19
  27. package/build/lib-client/user-with-mid-session.d.ts +2 -0
  28. package/build/lib-client/user-with-mid-session.js +33 -22
  29. package/build/lib-client/xsp-fs/attrs.js +4 -2
  30. package/build/lib-client/xsp-fs/exceptions.js +5 -2
  31. package/build/lib-client/xsp-fs/folder-node-serialization.js +4 -2
  32. package/build/lib-client/xsp-fs/node-in-fs.js +2 -5
  33. package/build/lib-common/async-fs-node.d.ts +30 -46
  34. package/build/lib-common/async-fs-node.js +71 -309
  35. package/build/lib-common/awaitable-state.js +3 -1
  36. package/build/lib-common/exceptions/file.d.ts +1 -1
  37. package/build/lib-common/exceptions/file.js +11 -6
  38. package/build/lib-common/exceptions/runtime.d.ts +7 -1
  39. package/build/lib-common/exceptions/runtime.js +16 -2
  40. package/build/lib-common/objs-on-disk/obj-version-file.d.ts +1 -1
  41. package/build/lib-common/objs-on-disk/obj-version-file.js +35 -33
  42. package/build/lib-index.d.ts +1 -1
  43. package/package.json +1 -1
@@ -1211,6 +1211,7 @@ declare namespace web3n.files {
1211
1211
 
1212
1212
  interface UploadStartEvent extends UploadEventBase {
1213
1213
  type: 'upload-started';
1214
+ isRestart: boolean;
1214
1215
  totalBytesToUpload: number;
1215
1216
  }
1216
1217
 
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright (C) 2016 - 2018, 2020, 2025 3NSoft Inc.
2
+ Copyright (C) 2016 - 2018, 2020, 2025 - 2026 3NSoft Inc.
3
3
 
4
4
  This program is free software: you can redistribute it and/or modify it under
5
5
  the terms of the GNU General Public License as published by the Free Software
@@ -31,6 +31,7 @@ declare namespace web3n {
31
31
  type?: string;
32
32
  cause?: any;
33
33
  message?: string;
34
+ stack?: string;
34
35
  }
35
36
 
36
37
  interface ConnectException extends RuntimeException {
@@ -31,7 +31,6 @@ export declare class InboxEvents {
31
31
  readonly connectionEvent$: Observable<InboxConnectionStatus>;
32
32
  private readonly wsProc;
33
33
  private disconnectedAt;
34
- private connection;
35
34
  constructor(msgReceiver: MailRecipient, getMsg: (msgId: string) => Promise<IncomingMessage>, listNewMsgs: (fromTS: number) => Promise<MsgInfo[]>, rmMsg: (msgId: string) => Promise<void>, logError: LogError);
36
35
  private makeProc;
37
36
  whenConnected(): Promise<void>;
@@ -22,7 +22,6 @@ const retrieval_1 = require("../../../lib-common/service-api/asmail/retrieval");
22
22
  const operators_1 = require("rxjs/operators");
23
23
  const utils_for_observables_1 = require("../../../lib-common/utils-for-observables");
24
24
  const ws_ipc_1 = require("../../../lib-common/ipc/ws-ipc");
25
- const awaitable_state_1 = require("../../../lib-common/awaitable-state");
26
25
  function toInboxConnectionStatus(status, params) {
27
26
  return (0, ws_ipc_1.addToStatus)(status, {
28
27
  service: 'inbox',
@@ -53,7 +52,6 @@ class InboxEvents {
53
52
  this.connectionEvents = new rxjs_1.Subject();
54
53
  this.connectionEvent$ = this.connectionEvents.asObservable().pipe((0, operators_1.share)());
55
54
  this.disconnectedAt = undefined;
56
- this.connection = new awaitable_state_1.AwaitableState();
57
55
  this.wsProc = new ws_ipc_1.WebSocketListening(SERVER_EVENTS_RESTART_WAIT_SECS, this.makeProc.bind(this));
58
56
  this.wsProc.startListening();
59
57
  Object.seal(this);
@@ -65,10 +63,10 @@ class InboxEvents {
65
63
  next: ev => {
66
64
  this.connectionEvents.next(toInboxConnectionStatus(ev));
67
65
  if (ev.type === 'heartbeat') {
68
- this.connection.setState();
66
+ this.msgReceiver.connectedState.setState();
69
67
  }
70
68
  else if ((ev.type === 'heartbeat-skip') || (ev.type === 'disconnected')) {
71
- this.connection.clearState();
69
+ this.msgReceiver.connectedState.clearState();
72
70
  }
73
71
  }
74
72
  });
@@ -87,7 +85,7 @@ class InboxEvents {
87
85
  return proc$;
88
86
  }
89
87
  async whenConnected() {
90
- return this.connection.whenStateIsSet();
88
+ return this.msgReceiver.connectedState.whenStateIsSet();
91
89
  }
92
90
  async getMessage(msgId) {
93
91
  try {
@@ -58,7 +58,7 @@ class InboxOnServer {
58
58
  try {
59
59
  (0, file_1.ensureCorrectFS)(syncedFS, 'synced', true);
60
60
  const msgReceiver = new recipient_1.MailRecipient(r.address, r.getSigner, () => r.asmailResolver(r.address), r.makeNet());
61
- const downloader = new msg_downloader_1.MsgDownloader(msgReceiver, () => inbox.inboxEvents.whenConnected());
61
+ const downloader = new msg_downloader_1.MsgDownloader(msgReceiver);
62
62
  const cache = await cached_msgs_1.CachedMessages.makeFor(cachePath, downloader, r.logError);
63
63
  const indexSyncedFS = await (0, fs_sync_utils_1.getOrMakeAndUploadFolderIn)(syncedFS, MSG_INDEX_FOLDER);
64
64
  const index = await msg_indexing_1.MsgIndex.make(indexSyncedFS);
@@ -3,9 +3,8 @@ import { ObjDownloader } from "../../../lib-client/objs-on-disk/obj-on-disk";
3
3
  import { MsgMeta } from "../../../lib-common/service-api/asmail/retrieval";
4
4
  export declare class MsgDownloader {
5
5
  private readonly msgReceiver;
6
- private readonly whenConnected;
7
6
  private readonly runner;
8
- constructor(msgReceiver: MailRecipient, whenConnected: () => Promise<void>);
7
+ constructor(msgReceiver: MailRecipient);
9
8
  getMsgMeta(msgId: string): Promise<MsgMeta>;
10
9
  getObjDownloader(msgId: string): ObjDownloader;
11
10
  private getLayoutWithHeaderAndFirstSegs;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /*
3
- Copyright (C) 2016 - 2019, 2025 3NSoft Inc.
3
+ Copyright (C) 2016 - 2019, 2025 - 2026 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
@@ -21,9 +21,8 @@ const obj_on_disk_1 = require("../../../lib-client/objs-on-disk/obj-on-disk");
21
21
  const MAX_GETTING_CHUNK = 512 * 1024;
22
22
  const DOWNLOAD_START_CHUNK = 128 * 1024;
23
23
  class MsgDownloader {
24
- constructor(msgReceiver, whenConnected) {
24
+ constructor(msgReceiver) {
25
25
  this.msgReceiver = msgReceiver;
26
- this.whenConnected = whenConnected;
27
26
  this.runner = new obj_on_disk_1.DownloadsRunner();
28
27
  Object.freeze(this);
29
28
  }
@@ -36,7 +35,7 @@ class MsgDownloader {
36
35
  getSegs: (objId, v, start, end) => this.getSegs(msgId, objId, start, end),
37
36
  splitSegsDownloads: (start, end) => (0, obj_on_disk_1.splitSegsDownloads)(start, end, MAX_GETTING_CHUNK),
38
37
  schedule: this.runner.schedule.bind(this.runner),
39
- whenConnected: this.whenConnected
38
+ whenConnected: () => this.msgReceiver.connectedState.whenStateIsSet()
40
39
  };
41
40
  }
42
41
  async getLayoutWithHeaderAndFirstSegs(msgId, objId) {
@@ -409,7 +409,7 @@ class SyncedObj {
409
409
  }
410
410
  async getNumOfBytesNeedingDownload(version) {
411
411
  if (!this.status.isAmongRemote(version)) {
412
- if (this.localVers.has(version)) {
412
+ if (this.status.isLocalOnlyVersion(version)) {
413
413
  return 0;
414
414
  }
415
415
  else {
@@ -111,6 +111,7 @@ export declare class ObjStatus implements SyncedObjStatus, UploadStatusRecorder
111
111
  getNonGarbageVersions(): NonGarbage;
112
112
  removeCurrentVersion(): Promise<void>;
113
113
  private triggerSaveProc;
114
+ get upload(): UploadInfo | undefined;
114
115
  recordUploadStart(info: NewVersionUpload): Promise<void>;
115
116
  recordUploadInterimState(info: NewVersionUpload): Promise<void>;
116
117
  recordUploadCancellation(info: NewVersionUpload): Promise<void>;
@@ -147,6 +148,7 @@ export declare class ObjStatus implements SyncedObjStatus, UploadStatusRecorder
147
148
  versionBeforeUnsyncedRemoval(): number | undefined;
148
149
  adoptRemoteVersion(version?: number): Promise<void>;
149
150
  isAmongRemote(version: number): boolean;
151
+ isLocalOnlyVersion(version: number): boolean;
150
152
  }
151
153
  export declare function readAndCheckStatus(objFolder: string, objId: ObjId): Promise<ObjStatusInfo>;
152
154
  export declare function countBytesIn(info: UploadInfo): number;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /*
3
- Copyright (C) 2016 - 2020, 2022, 2025 3NSoft Inc.
3
+ Copyright (C) 2016 - 2020, 2022, 2025 - 2026 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
@@ -197,10 +197,7 @@ class ObjStatus {
197
197
  return;
198
198
  }
199
199
  else {
200
- throw (0, runtime_1.makeRuntimeException)('file', {
201
- path: (0, path_1.join)(this.objFolder, exports.STATUS_FILE_NAME),
202
- fsEtityType: 'file', message: `Upload is in progress`
203
- }, { concurrentUpdate: true });
200
+ throw (0, runtime_1.makeRuntimeException)('file', { path: (0, path_1.join)(this.objFolder, exports.STATUS_FILE_NAME), fsEtityType: 'file', message: `Upload is in progress` }, { concurrentUpdate: true }, true);
204
201
  }
205
202
  }
206
203
  if (!remote.isArchived && remote.current) {
@@ -237,6 +234,9 @@ class ObjStatus {
237
234
  }
238
235
  }
239
236
  }
237
+ get upload() {
238
+ return this.status.upload;
239
+ }
240
240
  recordUploadStart(info) {
241
241
  var _a;
242
242
  if (this.status.upload) {
@@ -567,6 +567,10 @@ class ObjStatus {
567
567
  }
568
568
  return false;
569
569
  }
570
+ isLocalOnlyVersion(version) {
571
+ var _a;
572
+ return (((_a = this.status.local) === null || _a === void 0 ? void 0 : _a.current) === version);
573
+ }
570
574
  }
571
575
  exports.ObjStatus = ObjStatus;
572
576
  Object.freeze(ObjStatus.prototype);
@@ -19,7 +19,6 @@ export declare class RemoteEvents {
19
19
  private readonly connectionEvents;
20
20
  readonly connectionEvent$: Observable<StorageConnectionStatus>;
21
21
  private readonly wsProc;
22
- private connection;
23
22
  constructor(remoteStorage: StorageOwner, files: ObjFiles, broadcastNodeEvent: Storage['broadcastNodeEvent'], logError: LogError);
24
23
  private makeProc;
25
24
  startListening(): void;
@@ -21,7 +21,6 @@ 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 awaitable_state_1 = require("../../../lib-common/awaitable-state");
25
24
  function toStorageConnectionStatus(status, params) {
26
25
  return (0, ws_ipc_1.addToStatus)(status, {
27
26
  service: 'storage',
@@ -41,21 +40,20 @@ class RemoteEvents {
41
40
  this.logError = logError;
42
41
  this.connectionEvents = new rxjs_1.Subject();
43
42
  this.connectionEvent$ = this.connectionEvents.asObservable().pipe((0, operators_1.share)());
44
- this.connection = new awaitable_state_1.AwaitableState();
45
43
  this.wsProc = new ws_ipc_1.WebSocketListening(SERVER_EVENTS_RESTART_WAIT_SECS, this.makeProc.bind(this));
46
44
  Object.seal(this);
47
45
  }
48
46
  makeProc() {
49
47
  return (0, rxjs_1.from)(this.remoteStorage.openEventSource().then(({ client, heartbeat }) => {
50
- this.connection.setState();
48
+ this.remoteStorage.connectedState.setState();
51
49
  heartbeat.subscribe({
52
50
  next: ev => {
53
51
  this.connectionEvents.next(toStorageConnectionStatus(ev));
54
52
  if (ev.type === 'heartbeat') {
55
- this.connection.setState();
53
+ this.remoteStorage.connectedState.setState();
56
54
  }
57
55
  else if ((ev.type === 'heartbeat-skip') || (ev.type === 'disconnected')) {
58
- this.connection.clearState();
56
+ this.remoteStorage.connectedState.clearState();
59
57
  }
60
58
  }
61
59
  });
@@ -76,8 +74,8 @@ class RemoteEvents {
76
74
  this.connectionEvents.complete();
77
75
  this.wsProc.close();
78
76
  }
79
- async whenConnected() {
80
- return this.connection.whenStateIsSet();
77
+ whenConnected() {
78
+ return this.remoteStorage.connectedState.whenStateIsSet();
81
79
  }
82
80
  absorbObjChange(client) {
83
81
  return (new rxjs_1.Observable(obs => client.subscribe(owner_1.events.objChanged.EVENT_NAME, obs)))
@@ -40,7 +40,7 @@ class SyncedStore {
40
40
  this.nodes = new common_1.NodesContainer();
41
41
  this.events = new utils_for_observables_1.Broadcast();
42
42
  this.remoteEvents = new remote_events_1.RemoteEvents(this.remoteStorage, this.files, this.broadcastNodeEvent.bind(this), this.logError);
43
- this.uploader = new upsyncer_1.UpSyncer(this.remoteStorage, this.whenConnected.bind(this), this.logError);
43
+ this.uploader = new upsyncer_1.UpSyncer(this.remoteStorage, this.logError);
44
44
  Object.seal(this);
45
45
  }
46
46
  static async makeAndStart(path, user, getSigner, getStorages, cryptor, remoteServiceUrl, net, logError) {
@@ -249,7 +249,7 @@ class SyncedStore {
249
249
  return this.remoteEvents.connectionEvent$;
250
250
  }
251
251
  whenConnected() {
252
- return this.remoteEvents.whenConnected();
252
+ return this.remoteStorage.connectedState.whenStateIsSet();
253
253
  }
254
254
  }
255
255
  exports.SyncedStore = SyncedStore;
@@ -8,13 +8,12 @@ import { UploadEventSink, UploadHeaderChange } from "../../../lib-client/xsp-fs/
8
8
  export type FileWriteTapOperator = MonoTypeOperatorFunction<FileWrite[]>;
9
9
  export declare class UpSyncer {
10
10
  private readonly remoteStorage;
11
- private readonly whenConnected;
12
11
  private readonly logError;
13
12
  private readonly execPools;
14
13
  private readonly tasksByObjIds;
15
14
  private readonly tasksByIds;
16
15
  private readonly syncedUploadStarts;
17
- constructor(remoteStorage: StorageOwner, whenConnected: () => Promise<void>, logError: LogError);
16
+ constructor(remoteStorage: StorageOwner, logError: LogError);
18
17
  start(): void;
19
18
  stop(): Promise<void>;
20
19
  removeCurrentVersionOf(obj: SyncedObj): Promise<void>;
@@ -27,9 +27,8 @@ const synced_1 = require("../../../lib-common/processes/synced");
27
27
  const MAX_CHUNK_SIZE = 512 * 1024;
28
28
  const MAX_FAST_UPLOAD = 2 * 1024 * 1024;
29
29
  class UpSyncer {
30
- constructor(remoteStorage, whenConnected, logError) {
30
+ constructor(remoteStorage, logError) {
31
31
  this.remoteStorage = remoteStorage;
32
- this.whenConnected = whenConnected;
33
32
  this.logError = logError;
34
33
  this.tasksByObjIds = new Map();
35
34
  this.tasksByIds = new Map();
@@ -52,7 +51,7 @@ class UpSyncer {
52
51
  }
53
52
  catch (exc) {
54
53
  if (exc.type === 'connect') {
55
- await this.whenConnected();
54
+ await this.remoteStorage.connectedState.whenStateIsSet();
56
55
  return this.removeCurrentVersionOf(obj);
57
56
  }
58
57
  else {
@@ -83,7 +82,7 @@ class UpSyncer {
83
82
  if (uploadHeader) {
84
83
  await obj.saveUploadHeaderFile(uploadHeader);
85
84
  }
86
- const task = await UploadTask.for(obj, localVersion, uploadVersion, uploadHeader === null || uploadHeader === void 0 ? void 0 : uploadHeader.uploadHeader, syncedBase, createOnRemote, uploadTaskId, eventSink, this.remoteStorage, this.whenConnected, async () => {
85
+ const task = await UploadTask.for(obj, localVersion, uploadVersion, uploadHeader === null || uploadHeader === void 0 ? void 0 : uploadHeader.uploadHeader, syncedBase, createOnRemote, uploadTaskId, eventSink, this.remoteStorage, async () => {
87
86
  if (this.tasksByIds.delete(task.taskId)) {
88
87
  this.tasksByObjIds.delete(task.objId);
89
88
  }
@@ -108,10 +107,9 @@ exports.UpSyncer = UpSyncer;
108
107
  Object.freeze(UpSyncer.prototype);
109
108
  Object.freeze(UpSyncer);
110
109
  class UploadTask {
111
- constructor(taskId, remoteStorage, whenConnected, objId, objStatus, src, info, uploadHeader, doAtCompletion, eventSink) {
110
+ constructor(taskId, remoteStorage, objId, objStatus, src, info, uploadHeader, doAtCompletion, eventSink, isRestart) {
112
111
  this.taskId = taskId;
113
112
  this.remoteStorage = remoteStorage;
114
- this.whenConnected = whenConnected;
115
113
  this.objId = objId;
116
114
  this.objStatus = objStatus;
117
115
  this.src = src;
@@ -122,29 +120,51 @@ class UploadTask {
122
120
  this.uploadCompletion = (0, deferred_1.defer)();
123
121
  this.execLabel = executorLabelFor(this.info.needUpload);
124
122
  this.totalBytesToUpload = (0, obj_status_1.countBytesIn)(this.info);
125
- this.emitUploadEvent('upload-started', { totalBytesToUpload: this.totalBytesToUpload });
123
+ this.emitUploadEvent('upload-started', { totalBytesToUpload: this.totalBytesToUpload, isRestart });
126
124
  Object.seal(this);
127
125
  }
128
- static async for(obj, localVersion, uploadVersion, uploadHeader, syncedBase, createObj, taskId, eventSink, remoteStorage, whenConnected, doAtCompletion) {
126
+ static async for(obj, localVersion, uploadVersion, uploadHeader, syncedBase, createObj, taskId, eventSink, remoteStorage, doAtCompletion) {
129
127
  const src = await obj.getObjSrcFromLocalAndSyncedBranch(localVersion);
130
- let needUpload;
131
- if (syncedBase) {
132
- const { diff, newSegsPackOrder } = await obj.diffForUploadOf(localVersion);
133
- needUpload = await diffVerUpload(src, uploadHeader, diff, newSegsPackOrder);
128
+ const objStatus = obj.statusObj();
129
+ if (objStatus.upload) {
130
+ const info = objStatus.upload;
131
+ if ((info.type === 'new-version')
132
+ && (info.localVersion === localVersion) && (info.uploadVersion === uploadVersion)) {
133
+ return new UploadTask(taskId, remoteStorage, obj.objId, objStatus, src, info, uploadHeader, doAtCompletion, eventSink, true);
134
+ }
135
+ else {
136
+ let message;
137
+ if (info.type === 'new-version') {
138
+ message = `Upload type ${info.type} of local version ${info.localVersion} as new remote ${info.uploadVersion} is already scheduled, and is different from uploading local version ${localVersion} as remote ${uploadVersion}.`;
139
+ }
140
+ else {
141
+ message = `Upload type ${info.type} is already scheduled`;
142
+ }
143
+ throw (0, exceptions_1.makeFSSyncException)('sync-task', {
144
+ alreadyUploading: true,
145
+ message
146
+ });
147
+ }
134
148
  }
135
149
  else {
136
- needUpload = await wholeVerUpload(src, uploadHeader, createObj);
150
+ let needUpload;
151
+ if (syncedBase) {
152
+ const { diff, newSegsPackOrder } = await obj.diffForUploadOf(localVersion);
153
+ needUpload = await diffVerUpload(src, uploadHeader, diff, newSegsPackOrder);
154
+ }
155
+ else {
156
+ needUpload = await wholeVerUpload(src, uploadHeader, createObj);
157
+ }
158
+ const info = {
159
+ type: 'new-version',
160
+ localVersion,
161
+ uploadVersion,
162
+ baseVersion: syncedBase,
163
+ needUpload
164
+ };
165
+ await objStatus.recordUploadStart(info);
166
+ return new UploadTask(taskId, remoteStorage, obj.objId, objStatus, src, info, uploadHeader, doAtCompletion, eventSink, false);
137
167
  }
138
- const info = {
139
- type: 'new-version',
140
- localVersion,
141
- uploadVersion,
142
- baseVersion: syncedBase,
143
- needUpload
144
- };
145
- const objStatus = obj.statusObj();
146
- await objStatus.recordUploadStart(info);
147
- return new UploadTask(taskId, remoteStorage, whenConnected, obj.objId, objStatus, src, info, uploadHeader, doAtCompletion, eventSink);
148
168
  }
149
169
  neededExecutor() {
150
170
  return (!this.info.needUpload ? undefined : this.execLabel);
@@ -211,13 +231,17 @@ class UploadTask {
211
231
  catch (exc) {
212
232
  if (exc.type === 'connect') {
213
233
  this.emitUploadEvent('upload-disconnected', {});
214
- await this.whenConnected();
234
+ await this.remoteStorage.connectedState.whenStateIsSet();
215
235
  return false;
216
236
  }
217
237
  else {
238
+ if (exc.unexpectedStatus && this.info.needUpload.transactionId) {
239
+ await this.remoteStorage.cancelTransaction(this.objId, this.info.needUpload.transactionId)
240
+ .catch(noop);
241
+ }
218
242
  this.info.needUpload = undefined;
219
243
  this.uploadCompletion.reject((0, exceptions_1.makeFSSyncException)(`obj-upload`, {
220
- message: `Fail to upload local version ${this.info.uploadVersion}`,
244
+ message: `Fail to upload version ${this.info.uploadVersion} of local version ${this.info.localVersion}`,
221
245
  localVersion: this.info.uploadVersion,
222
246
  cause: exc
223
247
  }));
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /*
3
- Copyright (C) 2015 - 2017, 2020, 2022, 2025 3NSoft Inc.
3
+ Copyright (C) 2015 - 2017, 2020, 2022, 2025 - 2026 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
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /*
3
- Copyright (C) 2015, 2017, 2025 3NSoft Inc.
3
+ Copyright (C) 2015, 2017, 2025 - 2026 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
@@ -26,12 +26,14 @@ const user_with_mid_session_1 = require("../user-with-mid-session");
26
26
  const service_locator_1 = require("../service-locator");
27
27
  const ws_ipc_1 = require("../../lib-common/ipc/ws-ipc");
28
28
  const http_1 = require("../../lib-common/exceptions/http");
29
+ const runtime_1 = require("../../lib-common/exceptions/runtime");
29
30
  function makeMsgNotFoundException(msgId) {
30
31
  const exc = {
31
32
  runtimeException: true,
32
33
  type: 'inbox',
33
34
  msgId,
34
- msgNotFound: true
35
+ msgNotFound: true,
36
+ stack: (0, runtime_1.getStackHere)(1)
35
37
  };
36
38
  return exc;
37
39
  }
@@ -41,7 +43,8 @@ function makeObjNotFoundException(msgId, objId) {
41
43
  type: 'inbox',
42
44
  msgId,
43
45
  objNotFound: true,
44
- objId
46
+ objId,
47
+ stack: (0, runtime_1.getStackHere)(1)
45
48
  };
46
49
  return exc;
47
50
  }
@@ -50,7 +53,8 @@ function makeMsgIsBrokenException(msgId) {
50
53
  runtimeException: true,
51
54
  type: 'inbox',
52
55
  msgId,
53
- msgIsBroken: true
56
+ msgIsBroken: true,
57
+ stack: (0, runtime_1.getStackHere)(1)
54
58
  };
55
59
  return exc;
56
60
  }