core-3nweb-client-lib 0.50.1 → 0.50.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.
@@ -296,6 +296,7 @@ declare namespace web3n.asmail {
296
296
  type: "inbox";
297
297
  msgId: string;
298
298
  msgNotFound?: true;
299
+ incompleteDelivery?: true;
299
300
  objNotFound?: true;
300
301
  objId?: string;
301
302
  msgIsBroken?: true;
@@ -18,6 +18,7 @@
18
18
  Object.defineProperty(exports, "__esModule", { value: true });
19
19
  exports.MsgDownloader = void 0;
20
20
  const obj_on_disk_1 = require("../../../lib-client/objs-on-disk/obj-on-disk");
21
+ const sleep_1 = require("../../../lib-common/processes/sleep");
21
22
  const MAX_GETTING_CHUNK = 512 * 1024;
22
23
  const DOWNLOAD_START_CHUNK = 128 * 1024;
23
24
  class MsgDownloader {
@@ -26,8 +27,23 @@ class MsgDownloader {
26
27
  this.runner = new obj_on_disk_1.DownloadsRunner();
27
28
  Object.freeze(this);
28
29
  }
29
- getMsgMeta(msgId) {
30
- return this.msgReceiver.getMsgMeta(msgId);
30
+ async getMsgMeta(msgId) {
31
+ let lastExc = undefined;
32
+ for (let attemptNum = 0; attemptNum < 10; attemptNum += 1) {
33
+ try {
34
+ return await this.msgReceiver.getMsgMeta(msgId, false);
35
+ }
36
+ catch (exc) {
37
+ if (exc.incompleteDelivery) {
38
+ lastExc = exc;
39
+ }
40
+ else {
41
+ throw exc;
42
+ }
43
+ }
44
+ await (0, sleep_1.sleep)((attemptNum < 2) ? 500 : attemptNum * 2000);
45
+ }
46
+ throw lastExc;
31
47
  }
32
48
  getObjDownloader(msgId) {
33
49
  return {
@@ -161,8 +161,14 @@ async function makePeersKeyring(keyringFS, localFS, random, logger) {
161
161
  });
162
162
  }
163
163
  const entryToLog = keysDB.getSendingPair(peerCAddr);
164
- await keysDB.saveIfNeeded();
165
- await logs.recordGettingCryptoFromPeer(entryToLog, peerAddr);
164
+ if (entryToLog) {
165
+ await keysDB.saveIfNeeded();
166
+ await logs.recordGettingCryptoFromPeer(entryToLog, peerAddr);
167
+ }
168
+ else {
169
+ // XXX we see code come here. sql not recording? why?
170
+ logger.logError(`Suggested sending pair somehow didn't get into db within this absorbNextPairSuggestedByPeer()`);
171
+ }
166
172
  }
167
173
  async function periodicCheckAndUploadOfData() {
168
174
  if (logs.numOfLogs() >= NUM_OF_LOGS_TO_START_CUT) {
@@ -5,6 +5,7 @@ import { SubscribingClient } from '../../lib-common/ipc/ws-ipc';
5
5
  type InboxException = web3n.asmail.InboxException;
6
6
  type Observer<T> = web3n.Observer<T>;
7
7
  export declare function makeMsgNotFoundException(msgId: string): InboxException;
8
+ export declare function makeMsgIncompleteException(msgId: string): InboxException;
8
9
  export declare function makeFailToDecryptMsgException(msgId: string): InboxException;
9
10
  export declare function makeObjNotFoundException(msgId: string, objId: string): InboxException;
10
11
  export declare function makeMsgIsBrokenException(msgId: string): InboxException;
@@ -12,7 +13,7 @@ export declare class MailRecipient extends ServiceUser {
12
13
  constructor(user: string, getSigner: IGetMailerIdSigner, mainUrlGetter: () => Promise<string>, net: NetClient);
13
14
  getNet(): NetClient;
14
15
  listMsgs(fromTS: number | undefined): Promise<api.listMsgs.Reply>;
15
- getMsgMeta(msgId: string): Promise<api.MsgMeta>;
16
+ getMsgMeta(msgId: string, allowIncomplete: boolean): Promise<api.MsgMeta>;
16
17
  /**
17
18
  * This method returns either first part of message object, or a whole of it,
18
19
  * depending on a given limit for segments. Returned promise resolves to a
@@ -18,6 +18,7 @@
18
18
  Object.defineProperty(exports, "__esModule", { value: true });
19
19
  exports.MailRecipient = void 0;
20
20
  exports.makeMsgNotFoundException = makeMsgNotFoundException;
21
+ exports.makeMsgIncompleteException = makeMsgIncompleteException;
21
22
  exports.makeFailToDecryptMsgException = makeFailToDecryptMsgException;
22
23
  exports.makeObjNotFoundException = makeObjNotFoundException;
23
24
  exports.makeMsgIsBrokenException = makeMsgIsBrokenException;
@@ -38,6 +39,16 @@ function makeMsgNotFoundException(msgId) {
38
39
  };
39
40
  return exc;
40
41
  }
42
+ function makeMsgIncompleteException(msgId) {
43
+ const exc = {
44
+ runtimeException: true,
45
+ type: 'inbox',
46
+ msgId,
47
+ incompleteDelivery: true,
48
+ stack: (0, runtime_1.getStackHere)(1)
49
+ };
50
+ return exc;
51
+ }
41
52
  function makeFailToDecryptMsgException(msgId) {
42
53
  const exc = {
43
54
  runtimeException: true,
@@ -98,14 +109,17 @@ class MailRecipient extends user_with_mid_session_1.ServiceUser {
98
109
  throw (0, http_1.makeUnexpectedStatusHTTPException)(rep);
99
110
  }
100
111
  }
101
- async getMsgMeta(msgId) {
112
+ async getMsgMeta(msgId, allowIncomplete) {
102
113
  const rep = await this.doBodylessSessionRequest({
103
114
  appPath: api.msgMetadata.genUrlEnd(msgId),
104
115
  method: 'GET',
105
116
  responseType: 'json'
106
117
  });
107
118
  if (rep.status === api.msgMetadata.SC.ok) {
108
- const { meta, errMsg } = api.sanitizedMeta(rep.data);
119
+ if (!allowIncomplete && !rep.data.deliveryCompletion) {
120
+ throw makeMsgIncompleteException(msgId);
121
+ }
122
+ const { meta, errMsg } = api.sanitizedMeta(rep.data, allowIncomplete);
109
123
  if (!meta) {
110
124
  throw (0, http_1.makeMalformedReplyHTTPException)(rep, {
111
125
  message: `Malformed message metadata in a server response: ${errMsg}`
@@ -74,8 +74,9 @@ export declare namespace msgMetadata {
74
74
  * This function returns either a checked version of given meta object, if it
75
75
  * passes as message meta, or undefined, otherwise.
76
76
  * @param meta is an object that is expected to be message meta
77
+ * @param allowIncomplete
77
78
  */
78
- export declare function sanitizedMeta(meta: MsgMeta): {
79
+ export declare function sanitizedMeta(meta: MsgMeta, allowIncomplete: boolean): {
79
80
  meta?: MsgMeta;
80
81
  errMsg?: string;
81
82
  };
@@ -94,21 +94,26 @@ Object.freeze(msgMetadata);
94
94
  * This function returns either a checked version of given meta object, if it
95
95
  * passes as message meta, or undefined, otherwise.
96
96
  * @param meta is an object that is expected to be message meta
97
+ * @param allowIncomplete
97
98
  */
98
- function sanitizedMeta(meta) {
99
+ function sanitizedMeta(meta, allowIncomplete) {
99
100
  if (typeof meta !== 'object') {
100
101
  return { errMsg: `is not a json object: ${JSON.stringify(meta)}` };
101
102
  }
102
- if (typeof meta.objs !== 'object') {
103
- return { errMsg: `objs field is not an object in: ${JSON.stringify(meta)}` };
104
- }
105
- for (const objId of Object.keys(meta.objs)) {
106
- const st = meta.objs[objId];
107
- if (typeof st.size.header !== 'number') {
108
- return { errMsg: `obj's header is not a number in: ${JSON.stringify(meta)}` };
103
+ if (typeof meta.objs === 'object') {
104
+ for (const objId of Object.keys(meta.objs)) {
105
+ const st = meta.objs[objId];
106
+ if (typeof st.size.header !== 'number') {
107
+ return { errMsg: `obj's header is not a number in: ${JSON.stringify(meta)}` };
108
+ }
109
+ if (st.completed && (st.size.segments === undefined)) {
110
+ return { errMsg: `obj's segments is not a number in: ${JSON.stringify(meta)}` };
111
+ }
109
112
  }
110
- if (st.completed && (st.size.segments === undefined)) {
111
- return { errMsg: `obj's segments is not a number in: ${JSON.stringify(meta)}` };
113
+ }
114
+ else {
115
+ if (!allowIncomplete) {
116
+ return { errMsg: `objs field is not an object in: ${JSON.stringify(meta)}` };
112
117
  }
113
118
  }
114
119
  // TODO add more checks and return new object instead of a given one
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "core-3nweb-client-lib",
3
- "version": "0.50.1",
3
+ "version": "0.50.3",
4
4
  "description": "3NWeb client core library, embeddable into different environments",
5
5
  "main": "build/lib-index.js",
6
6
  "types": "build/lib-index.d.ts",