core-3nweb-client-lib 0.28.2 → 0.28.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.
- package/build/api-defs/asmail.d.ts +30 -12
- package/build/{ipc-via-protobuf/asmail-cap.d.ts → core/asmail/asmail-cap-ipc.d.ts} +1 -1
- package/build/{ipc-via-protobuf/asmail-cap.js → core/asmail/asmail-cap-ipc.js} +33 -11
- package/build/core/asmail/delivery/common.d.ts +2 -0
- package/build/core/asmail/delivery/index.js +9 -7
- package/build/core/asmail/delivery/msg.d.ts +4 -2
- package/build/core/asmail/delivery/msg.js +33 -16
- package/build/core/asmail/delivery/per-recipient-wip.js +3 -3
- package/build/core/asmail/inbox/msg-indexing.js +57 -48
- package/build/core/id-manager/index.d.ts +1 -1
- package/build/{ipc-via-protobuf/mailerid.d.ts → core/id-manager/mailerid-cap-ipc.d.ts} +1 -1
- package/build/{ipc-via-protobuf/mailerid.js → core/id-manager/mailerid-cap-ipc.js} +4 -4
- package/build/core/index.js +2 -2
- package/build/core/{sign-in.d.ts → startup/sign-in.d.ts} +5 -5
- package/build/core/{sign-in.js → startup/sign-in.js} +2 -2
- package/build/core/{sign-up.d.ts → startup/sign-up.d.ts} +6 -6
- package/build/core/{sign-up.js → startup/sign-up.js} +7 -7
- package/build/{ipc-via-protobuf → core/startup}/startup-cap.d.ts +1 -1
- package/build/{ipc-via-protobuf → core/startup}/startup-cap.js +4 -4
- package/build/core/storage/index.d.ts +1 -1
- package/build/{ipc-via-protobuf/storage-cap.d.ts → core/storage/storage-cap-ipc.d.ts} +1 -1
- package/build/{ipc-via-protobuf/storage-cap.js → core/storage/storage-cap-ipc.js} +4 -4
- package/build/{ipc-via-protobuf → core-ipc}/bytes.d.ts +2 -2
- package/build/{ipc-via-protobuf → core-ipc}/bytes.js +2 -2
- package/build/core-ipc/common-caps.js +14 -14
- package/build/{ipc-via-protobuf → core-ipc}/file.d.ts +2 -2
- package/build/{ipc-via-protobuf → core-ipc}/file.js +2 -2
- package/build/{ipc-via-protobuf → core-ipc}/fs.d.ts +2 -2
- package/build/{ipc-via-protobuf → core-ipc}/fs.js +2 -2
- package/build/{ipc-via-protobuf → core-ipc}/log-cap.js +1 -1
- package/build/core-ipc/startup-caps.js +1 -1
- package/build/ipc.d.ts +4 -4
- package/build/ipc.js +4 -4
- package/build/lib-client/cryptor/cryptor-wasm.js +1 -1
- package/build/lib-client/cryptor/cryptor.wasm +0 -0
- package/build/protos/asmail.proto.js +272 -12
- package/package.json +1 -1
- package/protos/asmail.proto +6 -1
- /package/build/{ipc-via-protobuf → core-ipc}/log-cap.d.ts +0 -0
|
@@ -36,21 +36,28 @@ declare namespace web3n.asmail {
|
|
|
36
36
|
|
|
37
37
|
interface DeliveryProgress {
|
|
38
38
|
notConnected?: true;
|
|
39
|
-
allDone
|
|
39
|
+
allDone?: 'all-ok' | 'with-errors';
|
|
40
40
|
msgSize: number;
|
|
41
41
|
localMeta?: any;
|
|
42
42
|
recipients: {
|
|
43
43
|
[address: string]: {
|
|
44
44
|
done: boolean;
|
|
45
45
|
idOnDelivery?: string;
|
|
46
|
-
|
|
46
|
+
deliveryTS?: number;
|
|
47
|
+
err?: DeliveryException | RuntimeException | Error;
|
|
47
48
|
bytesSent: number;
|
|
48
49
|
// XXX
|
|
49
|
-
|
|
50
|
+
awaitingRetry?: boolean;
|
|
51
|
+
failedAttempts?: {
|
|
52
|
+
attemptTS: number;
|
|
53
|
+
err: any;
|
|
54
|
+
}[];
|
|
50
55
|
}
|
|
51
56
|
};
|
|
52
57
|
}
|
|
53
58
|
|
|
59
|
+
type DeliveryException = ASMailSendException | ServLocException | ASMailSendException;
|
|
60
|
+
|
|
54
61
|
interface DeliveryOptions {
|
|
55
62
|
/**
|
|
56
63
|
* sendImmediately flag forces immediate delivery with true value.
|
|
@@ -63,9 +70,11 @@ declare namespace web3n.asmail {
|
|
|
63
70
|
*/
|
|
64
71
|
localMeta?: any;
|
|
65
72
|
|
|
73
|
+
// XXX
|
|
74
|
+
|
|
66
75
|
retryRecipient?: {
|
|
67
76
|
numOfAttempts: number;
|
|
68
|
-
// XXX default client says "ASAP" =>
|
|
77
|
+
// XXX default client says "ASAP" => core applies own sane default
|
|
69
78
|
timeBetweenAttempts?: number;
|
|
70
79
|
};
|
|
71
80
|
}
|
|
@@ -229,25 +238,25 @@ declare namespace web3n.asmail {
|
|
|
229
238
|
carbonCopy?: string[];
|
|
230
239
|
recipients?: string[];
|
|
231
240
|
}
|
|
232
|
-
|
|
241
|
+
|
|
233
242
|
interface MsgInfo {
|
|
234
243
|
msgId: string;
|
|
235
244
|
msgType: string;
|
|
236
245
|
deliveryTS: number;
|
|
237
246
|
}
|
|
238
|
-
|
|
247
|
+
|
|
239
248
|
interface IncomingMessage extends MsgInfo, MsgStruct {
|
|
240
249
|
sender: string;
|
|
241
250
|
establishedSenderKeyChain: boolean;
|
|
242
251
|
attachments?: files.ReadonlyFS;
|
|
243
252
|
// XXX info if not from the first attempt
|
|
244
253
|
}
|
|
245
|
-
|
|
254
|
+
|
|
246
255
|
interface OutgoingMessage extends MsgStruct {
|
|
247
256
|
msgId?: string;
|
|
248
257
|
attachments?: AttachmentsContainer;
|
|
249
258
|
}
|
|
250
|
-
|
|
259
|
+
|
|
251
260
|
/**
|
|
252
261
|
* This container is for entities that will be present in attachments
|
|
253
262
|
* fs/folder of recipient's incoming message.
|
|
@@ -260,7 +269,7 @@ declare namespace web3n.asmail {
|
|
|
260
269
|
[name: string]: files.FS;
|
|
261
270
|
};
|
|
262
271
|
}
|
|
263
|
-
|
|
272
|
+
|
|
264
273
|
interface InboxException extends RuntimeException {
|
|
265
274
|
type: "inbox";
|
|
266
275
|
msgId: string;
|
|
@@ -269,14 +278,23 @@ declare namespace web3n.asmail {
|
|
|
269
278
|
objId?: string;
|
|
270
279
|
msgIsBroken?: true;
|
|
271
280
|
}
|
|
272
|
-
|
|
281
|
+
|
|
273
282
|
interface ServLocException extends RuntimeException {
|
|
274
283
|
type: 'service-locating';
|
|
275
284
|
address: string;
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* domainNotFound flag indicates that domain in the address doesn't exist.
|
|
288
|
+
*/
|
|
276
289
|
domainNotFound?: true;
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* noServiceRecord flag indicates that 3NWeb services are not set at
|
|
293
|
+
* domain in the address.
|
|
294
|
+
*/
|
|
277
295
|
noServiceRecord?: true;
|
|
278
296
|
}
|
|
279
|
-
|
|
297
|
+
|
|
280
298
|
interface ASMailSendException extends RuntimeException {
|
|
281
299
|
type: 'asmail-delivery';
|
|
282
300
|
address?: string;
|
|
@@ -297,5 +315,5 @@ declare namespace web3n.asmail {
|
|
|
297
315
|
// errors that are due to this side
|
|
298
316
|
msgCancelled?: true;
|
|
299
317
|
}
|
|
300
|
-
|
|
318
|
+
|
|
301
319
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ExposedObj, Caller, ExposedServices } from '
|
|
1
|
+
import { ExposedObj, Caller, ExposedServices } from '../../ipc-via-protobuf/connector';
|
|
2
2
|
declare type ASMailService = web3n.asmail.Service;
|
|
3
3
|
export declare function exposeASMailCAP(cap: ASMailService, expServices: ExposedServices): ExposedObj<ASMailService>;
|
|
4
4
|
export declare function makeASMailCaller(caller: Caller, objPath: string[]): ASMailService;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/*
|
|
3
|
-
Copyright (C) 2020 -
|
|
3
|
+
Copyright (C) 2020 - 2023 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
|
|
@@ -17,14 +17,14 @@
|
|
|
17
17
|
*/
|
|
18
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
19
|
exports.makeASMailCaller = exports.exposeASMailCAP = void 0;
|
|
20
|
-
const protobuf_msg_1 = require("
|
|
21
|
-
const protobuf_type_1 = require("
|
|
22
|
-
const asmail_proto_1 = require("
|
|
23
|
-
const connector_1 = require("
|
|
20
|
+
const protobuf_msg_1 = require("../../ipc-via-protobuf/protobuf-msg");
|
|
21
|
+
const protobuf_type_1 = require("../../lib-client/protobuf-type");
|
|
22
|
+
const asmail_proto_1 = require("../../protos/asmail.proto");
|
|
23
|
+
const connector_1 = require("../../ipc-via-protobuf/connector");
|
|
24
24
|
const rxjs_1 = require("rxjs");
|
|
25
25
|
const operators_1 = require("rxjs/operators");
|
|
26
|
-
const fs_1 = require("
|
|
27
|
-
const utils_for_observables_1 = require("
|
|
26
|
+
const fs_1 = require("../../core-ipc/fs");
|
|
27
|
+
const utils_for_observables_1 = require("../../lib-common/utils-for-observables");
|
|
28
28
|
function exposeASMailCAP(cap, expServices) {
|
|
29
29
|
const out = cap.delivery;
|
|
30
30
|
const box = cap.inbox;
|
|
@@ -328,12 +328,33 @@ var addMsg;
|
|
|
328
328
|
}
|
|
329
329
|
return msg;
|
|
330
330
|
}
|
|
331
|
+
function retryOptToMsg(opt) {
|
|
332
|
+
if (!opt) {
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
return {
|
|
336
|
+
numOfAttempts: opt.numOfAttempts,
|
|
337
|
+
timeBetweenAttempts: (!!opt.timeBetweenAttempts ?
|
|
338
|
+
opt.timeBetweenAttempts : 0)
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
function retryOptFromMsg(msg) {
|
|
342
|
+
if (!msg) {
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
345
|
+
return {
|
|
346
|
+
numOfAttempts: msg.numOfAttempts,
|
|
347
|
+
timeBetweenAttempts: (!!msg.timeBetweenAttempts ?
|
|
348
|
+
msg.timeBetweenAttempts : undefined)
|
|
349
|
+
};
|
|
350
|
+
}
|
|
331
351
|
function wrapService(fn, expServices) {
|
|
332
352
|
return (reqBody) => {
|
|
333
|
-
const { id, recipients, msg, localMeta, sendImmediately } = requestType.unpack(reqBody);
|
|
353
|
+
const { id, recipients, msg, localMeta, sendImmediately, retryRecipient } = requestType.unpack(reqBody);
|
|
334
354
|
const promise = fn((0, protobuf_msg_1.fixArray)(recipients), unpackMsg(msg, expServices), id, {
|
|
335
355
|
localMeta: (0, protobuf_msg_1.valOfOptAny)(localMeta),
|
|
336
|
-
sendImmediately: (0, protobuf_msg_1.valOfOpt)(sendImmediately)
|
|
356
|
+
sendImmediately: (0, protobuf_msg_1.valOfOpt)(sendImmediately),
|
|
357
|
+
retryRecipient: retryOptFromMsg(retryRecipient)
|
|
337
358
|
});
|
|
338
359
|
return { promise };
|
|
339
360
|
};
|
|
@@ -346,6 +367,7 @@ var addMsg;
|
|
|
346
367
|
if (opts) {
|
|
347
368
|
req.sendImmediately = (0, protobuf_msg_1.toOptVal)(opts.sendImmediately);
|
|
348
369
|
req.localMeta = (0, protobuf_msg_1.toOptAny)(opts.localMeta);
|
|
370
|
+
req.retryRecipient = retryOptToMsg(opts.retryRecipient);
|
|
349
371
|
}
|
|
350
372
|
await caller.startPromiseCall(path, requestType.pack(req));
|
|
351
373
|
};
|
|
@@ -383,7 +405,7 @@ const deliveryProgressMsgType = protobuf_type_1.ProtoType.for(asmail_proto_1.asm
|
|
|
383
405
|
function packDeliveryProgress(p) {
|
|
384
406
|
const m = {
|
|
385
407
|
notConnected: (0, protobuf_msg_1.toOptVal)(p.notConnected),
|
|
386
|
-
allDone: p.allDone,
|
|
408
|
+
allDone: (0, protobuf_msg_1.toOptVal)(p.allDone),
|
|
387
409
|
msgSize: p.msgSize,
|
|
388
410
|
localMeta: (0, protobuf_msg_1.toOptAny)(p.localMeta),
|
|
389
411
|
recipients: []
|
|
@@ -403,7 +425,7 @@ function packDeliveryProgress(p) {
|
|
|
403
425
|
}
|
|
404
426
|
function unpackDeliveryProgress(m) {
|
|
405
427
|
const p = {
|
|
406
|
-
allDone: m.allDone,
|
|
428
|
+
allDone: (0, protobuf_msg_1.valOfOpt)(m.allDone),
|
|
407
429
|
msgSize: (0, protobuf_msg_1.fixInt)(m.msgSize),
|
|
408
430
|
notConnected: (0, protobuf_msg_1.valOfOpt)(m.notConnected),
|
|
409
431
|
localMeta: (0, protobuf_msg_1.valOfOptAny)(m.localMeta),
|
|
@@ -9,6 +9,7 @@ import { LogWarning, LogError } from '../../../lib-client/logging/log-to-file';
|
|
|
9
9
|
import { ServiceLocator } from '../../../lib-client/service-locator';
|
|
10
10
|
declare type OutgoingMessage = web3n.asmail.OutgoingMessage;
|
|
11
11
|
declare type DeliveryProgress = web3n.asmail.DeliveryProgress;
|
|
12
|
+
declare type DeliveryOptions = web3n.asmail.DeliveryOptions;
|
|
12
13
|
declare type AttachmentsContainer = web3n.asmail.AttachmentsContainer;
|
|
13
14
|
declare type FS = web3n.files.FS;
|
|
14
15
|
declare type WritableFS = web3n.files.WritableFS;
|
|
@@ -84,6 +85,7 @@ export interface SavedMsgToSend {
|
|
|
84
85
|
msgToSend: OutgoingMessage;
|
|
85
86
|
sender: string;
|
|
86
87
|
recipients: string[];
|
|
88
|
+
retryOpts: DeliveryOptions['retryRecipient'];
|
|
87
89
|
}
|
|
88
90
|
/**
|
|
89
91
|
* This is a utility function that adds a number into given number line
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/*
|
|
3
|
-
Copyright (C) 2016 - 2017, 2020 -
|
|
3
|
+
Copyright (C) 2016 - 2017, 2020 - 2023 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
|
|
@@ -51,10 +51,10 @@ class Delivery {
|
|
|
51
51
|
*/
|
|
52
52
|
this.queuedDelivery = [];
|
|
53
53
|
this.allDeliveries = new rxjs_1.Subject();
|
|
54
|
-
this.allDeliveries$ = this.allDeliveries.asObservable()
|
|
54
|
+
this.allDeliveries$ = this.allDeliveries.asObservable()
|
|
55
|
+
.pipe((0, operators_1.share)());
|
|
55
56
|
(0, file_1.ensureCorrectFS)(fs, 'local', true);
|
|
56
|
-
this.r.notifyMsgProgress =
|
|
57
|
-
(id, progress) => this.allDeliveries.next({ id, progress });
|
|
57
|
+
this.r.notifyMsgProgress = (id, progress) => this.allDeliveries.next({ id, progress });
|
|
58
58
|
Object.freeze(this.r);
|
|
59
59
|
Object.freeze(this);
|
|
60
60
|
}
|
|
@@ -152,12 +152,12 @@ class Delivery {
|
|
|
152
152
|
throw new Error(`Message with id ${id} has already been added for delivery`);
|
|
153
153
|
}
|
|
154
154
|
const attachments = common_1.Attachments.fromMsg(msgToSend);
|
|
155
|
-
const localMeta =
|
|
155
|
+
const localMeta = opts === null || opts === void 0 ? void 0 : opts.localMeta;
|
|
156
156
|
// save msg, in case delivery should be restarted
|
|
157
157
|
const msgFS = await this.makeFSForNewMsg(id);
|
|
158
|
-
const msg = await msg_1.Msg.forNew(id, msgFS, msgToSend, sender, recipients, this.r, attachments, localMeta);
|
|
158
|
+
const msg = await msg_1.Msg.forNew(id, msgFS, msgToSend, sender, recipients, this.r, attachments, localMeta, opts === null || opts === void 0 ? void 0 : opts.retryRecipient);
|
|
159
159
|
// add and schedule
|
|
160
|
-
const sendImmediately = (opts ?
|
|
160
|
+
const sendImmediately = !!(opts === null || opts === void 0 ? void 0 : opts.sendImmediately);
|
|
161
161
|
this.addMsgAndSchedule(msg, sendImmediately);
|
|
162
162
|
}
|
|
163
163
|
async makeFSForNewMsg(id) {
|
|
@@ -187,6 +187,7 @@ class Delivery {
|
|
|
187
187
|
this.performQueuedDelivery();
|
|
188
188
|
}
|
|
189
189
|
}, async (err) => {
|
|
190
|
+
// XXX add to retries queue with some timestamp
|
|
190
191
|
await this.r.logWarning('Got error when sending a message', err);
|
|
191
192
|
this.immediateDelivery.delete(msg);
|
|
192
193
|
this.performQueuedDelivery();
|
|
@@ -217,6 +218,7 @@ class Delivery {
|
|
|
217
218
|
}
|
|
218
219
|
}
|
|
219
220
|
}, async (err) => {
|
|
221
|
+
// XXX add to retries queue with some timestamp
|
|
220
222
|
await this.r.logWarning('Got error when sending a message', err);
|
|
221
223
|
if (msg === this.queuedDelivery[0]) {
|
|
222
224
|
this.queuedDelivery.shift();
|
|
@@ -5,6 +5,7 @@ import { Observable } from 'rxjs';
|
|
|
5
5
|
declare type WritableFS = web3n.files.WritableFS;
|
|
6
6
|
declare type DeliveryProgress = web3n.asmail.DeliveryProgress;
|
|
7
7
|
declare type OutgoingMessage = web3n.asmail.OutgoingMessage;
|
|
8
|
+
declare type DeliveryOptions = web3n.asmail.DeliveryOptions;
|
|
8
9
|
export declare class Msg {
|
|
9
10
|
readonly id: string;
|
|
10
11
|
readonly r: ResourcesForSending;
|
|
@@ -16,6 +17,7 @@ export declare class Msg {
|
|
|
16
17
|
private cancelled;
|
|
17
18
|
private sender;
|
|
18
19
|
private recipients;
|
|
20
|
+
private retryOpts;
|
|
19
21
|
private msgToSend;
|
|
20
22
|
private attachments;
|
|
21
23
|
private sequentialWIP;
|
|
@@ -25,10 +27,10 @@ export declare class Msg {
|
|
|
25
27
|
private readonly progressPublisher;
|
|
26
28
|
get progress$(): Observable<DeliveryProgress>;
|
|
27
29
|
private constructor();
|
|
28
|
-
static forNew(id: string, msgFS: WritableFS, msgToSend: OutgoingMessage, sender: string, recipients: string[], r: ResourcesForSending, attachments: Attachments | undefined, localMeta: any | undefined): Promise<Msg>;
|
|
30
|
+
static forNew(id: string, msgFS: WritableFS, msgToSend: OutgoingMessage, sender: string, recipients: string[], r: ResourcesForSending, attachments: Attachments | undefined, localMeta: any | undefined, retryOpts: DeliveryOptions['retryRecipient']): Promise<Msg>;
|
|
29
31
|
static forRestart(id: string, msgFS: WritableFS, r: ResourcesForSending): Promise<Msg>;
|
|
30
32
|
private save;
|
|
31
|
-
|
|
33
|
+
notifyOfChangesInProgress(saveProgress: boolean, saveWIPs: boolean): void;
|
|
32
34
|
msgPacker(pack?: PackJSON): Promise<MsgPacker>;
|
|
33
35
|
isDone(): boolean;
|
|
34
36
|
isSendingNow(): boolean;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/*
|
|
3
|
-
Copyright (C) 2016 - 2018, 2020 3NSoft Inc.
|
|
3
|
+
Copyright (C) 2016 - 2018, 2020, 2023 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
|
|
@@ -28,6 +28,8 @@ const MAIN_OBJ_FILE_NAME = 'msg.json';
|
|
|
28
28
|
const PROGRESS_INFO_FILE_NAME = 'progress.json';
|
|
29
29
|
const WIPS_INFO_FILE_NAME = 'wips.json';
|
|
30
30
|
function checkIfAllRecipientsDone(progress) {
|
|
31
|
+
// XXX this is missing info about already attempted sending, producing
|
|
32
|
+
/// true, when retries are needed.
|
|
31
33
|
for (const recipient of Object.keys(progress.recipients)) {
|
|
32
34
|
const recInfo = progress.recipients[recipient];
|
|
33
35
|
if (!recInfo.done) {
|
|
@@ -36,6 +38,15 @@ function checkIfAllRecipientsDone(progress) {
|
|
|
36
38
|
}
|
|
37
39
|
return true;
|
|
38
40
|
}
|
|
41
|
+
function hasError(progress) {
|
|
42
|
+
for (const recipient of Object.keys(progress.recipients)) {
|
|
43
|
+
const recInfo = progress.recipients[recipient];
|
|
44
|
+
if (recInfo.err) {
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
39
50
|
async function estimatedPackedSize(msgToSend, attachments) {
|
|
40
51
|
let totalSize = (0, common_1.estimatePackedSizeOf)(buffer_utils_1.utf8.pack(JSON.stringify(msgToSend)).length);
|
|
41
52
|
if (attachments) {
|
|
@@ -55,6 +66,7 @@ class Msg {
|
|
|
55
66
|
this.cancelled = false;
|
|
56
67
|
this.sender = undefined;
|
|
57
68
|
this.recipients = undefined;
|
|
69
|
+
this.retryOpts = undefined;
|
|
58
70
|
this.msgToSend = undefined;
|
|
59
71
|
this.attachments = undefined;
|
|
60
72
|
this.sequentialWIP = undefined;
|
|
@@ -65,9 +77,8 @@ class Msg {
|
|
|
65
77
|
get progress$() {
|
|
66
78
|
return this.progressPublisher.asObservable();
|
|
67
79
|
}
|
|
68
|
-
static async forNew(id, msgFS, msgToSend, sender, recipients, r, attachments, localMeta) {
|
|
80
|
+
static async forNew(id, msgFS, msgToSend, sender, recipients, r, attachments, localMeta, retryOpts) {
|
|
69
81
|
const progress = {
|
|
70
|
-
allDone: false,
|
|
71
82
|
msgSize: await estimatedPackedSize(msgToSend, attachments),
|
|
72
83
|
recipients: {}
|
|
73
84
|
};
|
|
@@ -81,6 +92,7 @@ class Msg {
|
|
|
81
92
|
msg.msgToSend = msgToSend;
|
|
82
93
|
msg.sender = sender;
|
|
83
94
|
msg.recipients = recipients;
|
|
95
|
+
msg.retryOpts = retryOpts;
|
|
84
96
|
msg.attachments = attachments;
|
|
85
97
|
if (localMeta !== undefined) {
|
|
86
98
|
msg.progress.localMeta = localMeta;
|
|
@@ -100,7 +112,7 @@ class Msg {
|
|
|
100
112
|
msg.recipients = main.recipients;
|
|
101
113
|
msg.attachments = await common_1.Attachments.readFrom(msgFS);
|
|
102
114
|
if (await msgFS.checkFilePresence(WIPS_INFO_FILE_NAME)) {
|
|
103
|
-
msg.wipsInfo = (await msgFS.readJSONFile(WIPS_INFO_FILE_NAME))
|
|
115
|
+
msg.wipsInfo = (await msgFS.readJSONFile(WIPS_INFO_FILE_NAME));
|
|
104
116
|
}
|
|
105
117
|
return msg;
|
|
106
118
|
}
|
|
@@ -108,7 +120,8 @@ class Msg {
|
|
|
108
120
|
const main = {
|
|
109
121
|
msgToSend: this.msgToSend,
|
|
110
122
|
sender: this.sender,
|
|
111
|
-
recipients: this.recipients
|
|
123
|
+
recipients: this.recipients,
|
|
124
|
+
retryOpts: this.retryOpts
|
|
112
125
|
};
|
|
113
126
|
await this.msgFS.writeJSONFile(MAIN_OBJ_FILE_NAME, main, { create: true, exclusive: true });
|
|
114
127
|
await this.msgFS.writeJSONFile(PROGRESS_INFO_FILE_NAME, this.progress, { create: true, exclusive: true });
|
|
@@ -116,28 +129,31 @@ class Msg {
|
|
|
116
129
|
await this.attachments.linkIn(this.msgFS);
|
|
117
130
|
}
|
|
118
131
|
}
|
|
119
|
-
|
|
132
|
+
notifyOfChangesInProgress(saveProgress, saveWIPs) {
|
|
120
133
|
if (this.cancelled) {
|
|
121
134
|
return;
|
|
122
135
|
}
|
|
123
136
|
if (this.progress.allDone) {
|
|
124
137
|
return;
|
|
125
138
|
}
|
|
139
|
+
// XXX check progress differently
|
|
140
|
+
// Indicate need for restart ?
|
|
141
|
+
// In recipient's part, awaitingRestart flag ?
|
|
142
|
+
// retryRecipients ?
|
|
126
143
|
if (checkIfAllRecipientsDone(this.progress)) {
|
|
127
|
-
this.progress.allDone =
|
|
144
|
+
this.progress.allDone = (hasError(this.progress) ?
|
|
145
|
+
'with-errors' : 'all-ok');
|
|
128
146
|
saveProgress = true;
|
|
129
147
|
}
|
|
130
148
|
this.r.notifyMsgProgress(this.id, (0, json_utils_1.copy)(this.progress));
|
|
131
149
|
this.progressPublisher.next((0, json_utils_1.copy)(this.progress));
|
|
132
150
|
if (saveProgress) {
|
|
133
|
-
this.progressSavingProc.startOrChain(
|
|
134
|
-
await this.msgFS.writeJSONFile(PROGRESS_INFO_FILE_NAME, this.progress, {});
|
|
135
|
-
});
|
|
151
|
+
this.progressSavingProc.startOrChain(() => this.msgFS.writeJSONFile(PROGRESS_INFO_FILE_NAME, this.progress, {}));
|
|
136
152
|
}
|
|
137
153
|
if (this.isDone()) {
|
|
138
154
|
this.progressPublisher.complete();
|
|
139
155
|
this.progressSavingProc.startOrChain(async () => {
|
|
140
|
-
await this.msgFS.deleteFile(WIPS_INFO_FILE_NAME).catch(
|
|
156
|
+
await this.msgFS.deleteFile(WIPS_INFO_FILE_NAME).catch(noop);
|
|
141
157
|
if (this.attachments) {
|
|
142
158
|
await this.attachments.deleteFrom(this.msgFS);
|
|
143
159
|
}
|
|
@@ -174,7 +190,7 @@ class Msg {
|
|
|
174
190
|
return msg;
|
|
175
191
|
}
|
|
176
192
|
isDone() {
|
|
177
|
-
return this.progress.allDone;
|
|
193
|
+
return !!this.progress.allDone;
|
|
178
194
|
}
|
|
179
195
|
isSendingNow() {
|
|
180
196
|
return !!this.sendingProc.isProcessing();
|
|
@@ -261,12 +277,12 @@ class Msg {
|
|
|
261
277
|
}
|
|
262
278
|
});
|
|
263
279
|
await Promise.all(wipPromises);
|
|
264
|
-
|
|
280
|
+
// XXX ???
|
|
265
281
|
if (this.completionPromise && this.isDone()) {
|
|
266
282
|
this.completionPromise.resolve(this.progress);
|
|
267
283
|
this.completionPromise = undefined;
|
|
268
284
|
}
|
|
269
|
-
}
|
|
285
|
+
}).catch(err => {
|
|
270
286
|
if (this.completionPromise) {
|
|
271
287
|
this.completionPromise.reject(err);
|
|
272
288
|
this.completionPromise = undefined;
|
|
@@ -311,12 +327,12 @@ class Msg {
|
|
|
311
327
|
if (this.sequentialWIP.isDone()) {
|
|
312
328
|
this.sequentialWIP = undefined;
|
|
313
329
|
}
|
|
314
|
-
|
|
330
|
+
// XXX ???
|
|
315
331
|
if (this.completionPromise && this.isDone()) {
|
|
316
332
|
this.completionPromise.resolve(this.progress);
|
|
317
333
|
this.completionPromise = undefined;
|
|
318
334
|
}
|
|
319
|
-
}
|
|
335
|
+
}).catch(err => {
|
|
320
336
|
if (this.completionPromise) {
|
|
321
337
|
this.completionPromise.reject(err);
|
|
322
338
|
this.completionPromise = undefined;
|
|
@@ -327,4 +343,5 @@ class Msg {
|
|
|
327
343
|
exports.Msg = Msg;
|
|
328
344
|
Object.freeze(Msg.prototype);
|
|
329
345
|
Object.freeze(Msg);
|
|
346
|
+
function noop() { }
|
|
330
347
|
Object.freeze(exports);
|
|
@@ -112,7 +112,7 @@ class WIP {
|
|
|
112
112
|
throw new Error(`Unknown wip stage ${stage}`);
|
|
113
113
|
}
|
|
114
114
|
return proc.catch(async (err) => {
|
|
115
|
-
|
|
115
|
+
this.updateInfo(0, true, err);
|
|
116
116
|
this.state.stage = undefined;
|
|
117
117
|
});
|
|
118
118
|
}
|
|
@@ -238,7 +238,7 @@ class WIP {
|
|
|
238
238
|
}
|
|
239
239
|
recInfo.done = true;
|
|
240
240
|
delete this.msg.wipsInfo[this.state.recipient];
|
|
241
|
-
this.msg.
|
|
241
|
+
this.msg.notifyOfChangesInProgress(true, this.doStateRecording);
|
|
242
242
|
}
|
|
243
243
|
else {
|
|
244
244
|
this.state.bytesUploaded += bytesSent;
|
|
@@ -250,7 +250,7 @@ class WIP {
|
|
|
250
250
|
else {
|
|
251
251
|
saveWIPs = false;
|
|
252
252
|
}
|
|
253
|
-
this.msg.
|
|
253
|
+
this.msg.notifyOfChangesInProgress(false, saveWIPs);
|
|
254
254
|
}
|
|
255
255
|
}
|
|
256
256
|
async sendMeta() {
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
*/
|
|
18
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
19
|
exports.MsgIndex = void 0;
|
|
20
|
+
const synced_1 = require("../../../lib-common/processes/synced");
|
|
20
21
|
const timed_cache_1 = require("../../../lib-common/timed-cache");
|
|
21
22
|
const lib_sqlite_on_3nstorage_1 = require("../../../lib-sqlite-on-3nstorage");
|
|
22
23
|
const file_1 = require("../../../lib-common/exceptions/file");
|
|
@@ -271,6 +272,8 @@ class LogAndStructFiles {
|
|
|
271
272
|
this.logsFS = logsFS;
|
|
272
273
|
this.dbsFS = dbsFS;
|
|
273
274
|
this.syncing = undefined;
|
|
275
|
+
// XXX synchronize file saving
|
|
276
|
+
this.logsFSaccessProc = new synced_1.SingleProc();
|
|
274
277
|
(0, file_1.ensureCorrectFS)(this.logsFS, 'synced', true);
|
|
275
278
|
Object.seal(this);
|
|
276
279
|
}
|
|
@@ -319,33 +322,35 @@ class LogAndStructFiles {
|
|
|
319
322
|
logNums.sort();
|
|
320
323
|
return logNums;
|
|
321
324
|
}
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
325
|
+
createNewLogFile(logNum, jsonStr = '[]') {
|
|
326
|
+
return this.logsFSaccessProc.startOrChain(async () => {
|
|
327
|
+
const logFile = this.logFileName(logNum);
|
|
328
|
+
const version = await this.logsFS.v.writeTxtFile(logFile, jsonStr, { create: true, exclusive: true });
|
|
329
|
+
// XXX sync disabled for now, and may be need another structure
|
|
330
|
+
// await this.logsFS.v!.sync!.upload(logFile);
|
|
331
|
+
// await this.logsFS.v!.sync!.upload('');
|
|
332
|
+
return {
|
|
333
|
+
num: logNum,
|
|
334
|
+
version,
|
|
335
|
+
writeOfs: jsonStr.length - 1
|
|
336
|
+
};
|
|
337
|
+
});
|
|
332
338
|
}
|
|
333
339
|
async statLogFile(logNum) {
|
|
334
340
|
const logFile = this.logFileName(logNum);
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
else if (syncState === 'unsynced') {
|
|
340
|
-
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
}
|
|
341
|
+
// XXX sync disabled for now, and may be need another structure
|
|
342
|
+
// const { state: syncState } = await this.logsFS.v!.sync!.status(logFile);
|
|
343
|
+
// if (syncState === 'behind') {
|
|
344
|
+
// await this.logsFS.v!.sync!.adoptRemote(logFile);
|
|
345
|
+
// } else if (syncState === 'unsynced') {
|
|
346
|
+
// await this.logsFS.v!.sync!.upload(logFile);
|
|
347
|
+
// } else if (syncState === 'conflicting') {
|
|
348
|
+
// // XXX
|
|
349
|
+
// throw new Error(`conflict resolution needs implementation`);
|
|
350
|
+
// }
|
|
346
351
|
const { size, version } = await this.logsFS.stat(logFile);
|
|
347
352
|
return {
|
|
348
|
-
syncState,
|
|
353
|
+
syncState: 'unsynced',
|
|
349
354
|
tail: {
|
|
350
355
|
num: logNum,
|
|
351
356
|
version: version,
|
|
@@ -354,32 +359,36 @@ class LogAndStructFiles {
|
|
|
354
359
|
};
|
|
355
360
|
}
|
|
356
361
|
async appendLogFile(logNum, bytes) {
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
await this.logsFS.v
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
//
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
362
|
+
return this.logsFSaccessProc.startOrChain(async () => {
|
|
363
|
+
const logFile = this.logFileName(logNum);
|
|
364
|
+
// XXX sync disabled for now, and may be need another structure
|
|
365
|
+
// const { state } = await this.logsFS.v!.sync!.status(logFile);
|
|
366
|
+
// if (state === 'behind') {
|
|
367
|
+
// await this.logsFS.v!.sync!.adoptRemote(logFile);
|
|
368
|
+
// } else if (state === 'conflicting') {
|
|
369
|
+
// // XXX
|
|
370
|
+
// throw new Error(`conflict resolution needs implementation`);
|
|
371
|
+
// }
|
|
372
|
+
const sink = await this.logsFS.getByteSink(logFile, { truncate: false });
|
|
373
|
+
const len = await sink.getSize();
|
|
374
|
+
let writeOfs;
|
|
375
|
+
if (len === 2) {
|
|
376
|
+
await sink.splice(len - 1, 1);
|
|
377
|
+
writeOfs = len - 1;
|
|
378
|
+
}
|
|
379
|
+
else {
|
|
380
|
+
await sink.splice(len - 1, 1, COMMA_BYTE);
|
|
381
|
+
writeOfs = len;
|
|
382
|
+
}
|
|
383
|
+
await sink.splice(writeOfs, 0, bytes);
|
|
384
|
+
writeOfs += bytes.length;
|
|
385
|
+
await sink.splice(writeOfs, 0, SQ_BRACKET_BYTE);
|
|
386
|
+
await sink.done();
|
|
387
|
+
// XXX sync disabled for now, and may be need another structure
|
|
388
|
+
// const uploadedVersion = (await this.logsFS.v!.sync!.upload(logFile))!;
|
|
389
|
+
const uploadedVersion = logNum;
|
|
390
|
+
return { uploadedVersion, writeOfs };
|
|
391
|
+
});
|
|
383
392
|
}
|
|
384
393
|
dbFileName(fileTS) {
|
|
385
394
|
return `${fileTS}${DB_EXT}`;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { user as mid } from '../../lib-common/mid-sigs-NaCl-Ed';
|
|
2
2
|
import { JsonKey } from '../../lib-common/jwkeys';
|
|
3
|
-
import { GenerateKey } from '../sign-in';
|
|
3
|
+
import { GenerateKey } from '../startup/sign-in';
|
|
4
4
|
import { LogError, LogWarning } from '../../lib-client/logging/log-to-file';
|
|
5
5
|
import { NetClient } from '../../lib-client/request-utils';
|
|
6
6
|
import { ServiceLocator } from '../../lib-client/service-locator';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Caller, ExposedObj } from "
|
|
1
|
+
import { Caller, ExposedObj } from "../../ipc-via-protobuf/connector";
|
|
2
2
|
declare type MailerId = web3n.mailerid.Service;
|
|
3
3
|
export declare function exposeMailerIdCAP(cap: MailerId): ExposedObj<MailerId>;
|
|
4
4
|
export declare function makeMailerIdCaller(caller: Caller, objPath: string[]): MailerId;
|