core-3nweb-client-lib 0.27.4 → 0.27.6

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 (86) hide show
  1. package/build/api-defs/files.d.ts +40 -10
  2. package/build/core/asmail/delivery/per-recipient-wip.js +2 -2
  3. package/build/core/asmail/inbox/inbox-events.js +10 -5
  4. package/build/core/asmail/inbox/index.d.ts +3 -2
  5. package/build/core/asmail/inbox/index.js +14 -10
  6. package/build/core/asmail/inbox/msg-indexing.d.ts +17 -64
  7. package/build/core/asmail/inbox/msg-indexing.js +440 -311
  8. package/build/core/asmail/inbox/msg-on-disk.js +2 -1
  9. package/build/core/asmail/index.js +3 -2
  10. package/build/core/asmail/keyring/correspondent-keys.js +3 -1
  11. package/build/core/asmail/keyring/index.d.ts +1 -4
  12. package/build/core/asmail/keyring/index.js +6 -6
  13. package/build/core/asmail/msg/opener.js +4 -3
  14. package/build/core/asmail/msg/packer.d.ts +1 -0
  15. package/build/core/asmail/msg/packer.js +8 -4
  16. package/build/core/index.js +2 -3
  17. package/build/core/storage/local/obj-files.js +2 -1
  18. package/build/core/storage/synced/storage.js +3 -2
  19. package/build/core/storage/synced/upload-header-file.js +4 -2
  20. package/build/core/storage/synced/upsyncer.js +3 -5
  21. package/build/ipc-via-protobuf/asmail-cap.js +14 -15
  22. package/build/ipc-via-protobuf/bytes.js +42 -18
  23. package/build/ipc-via-protobuf/file.js +43 -39
  24. package/build/ipc-via-protobuf/fs.js +72 -67
  25. package/build/ipc-via-protobuf/mailerid.js +2 -2
  26. package/build/ipc-via-protobuf/protobuf-msg.d.ts +1 -0
  27. package/build/ipc-via-protobuf/protobuf-msg.js +5 -1
  28. package/build/ipc-via-protobuf/startup-cap.js +8 -8
  29. package/build/ipc-via-protobuf/storage-cap.js +4 -4
  30. package/build/ipc.d.ts +1 -0
  31. package/build/ipc.js +3 -1
  32. package/build/lib-client/3nstorage/xsp-fs/common.js +2 -0
  33. package/build/lib-client/3nstorage/xsp-fs/file-node.js +0 -17
  34. package/build/lib-client/3nstorage/xsp-fs/file.d.ts +1 -1
  35. package/build/lib-client/3nstorage/xsp-fs/folder-node.d.ts +1 -1
  36. package/build/lib-client/3nstorage/xsp-fs/folder-node.js +13 -7
  37. package/build/lib-client/3nstorage/xsp-fs/fs.d.ts +1 -1
  38. package/build/lib-client/3nstorage/xsp-fs/fs.js +1 -1
  39. package/build/lib-client/3nstorage/xsp-fs/node-in-fs.d.ts +2 -2
  40. package/build/lib-client/3nstorage/xsp-fs/node-in-fs.js +7 -3
  41. package/build/lib-client/3nstorage/xsp-fs/node-persistence.d.ts +1 -0
  42. package/build/lib-client/3nstorage/xsp-fs/node-persistence.js +7 -5
  43. package/build/lib-client/3nstorage/xsp-fs/xsp-payload-v1.js +3 -4
  44. package/build/lib-client/3nstorage/xsp-fs/xsp-payload-v2.js +20 -15
  45. package/build/lib-client/cryptor/cryptor-in-worker.js +37 -47
  46. package/build/lib-client/cryptor/cryptor-wasm.js +1 -1
  47. package/build/lib-client/cryptor/cryptor.wasm +0 -0
  48. package/build/lib-client/cryptor/in-proc-js.js +15 -12
  49. package/build/lib-client/cryptor/in-proc-wasm.js +11 -8
  50. package/build/lib-client/cryptor/serialization-for-wasm.d.ts +36 -0
  51. package/build/lib-client/cryptor/serialization-for-wasm.js +58 -0
  52. package/build/lib-client/cryptor-work-labels.d.ts +26 -0
  53. package/build/lib-client/cryptor-work-labels.js +152 -0
  54. package/build/lib-client/fs-sync-utils.d.ts +7 -1
  55. package/build/lib-client/fs-sync-utils.js +18 -7
  56. package/build/lib-client/local-files/dev-file-src.d.ts +2 -1
  57. package/build/lib-client/local-files/dev-file-src.js +5 -1
  58. package/build/lib-client/local-files/device-fs.js +2 -1
  59. package/build/lib-client/objs-on-disk/obj-on-disk.js +5 -1
  60. package/build/lib-client/request-utils.js +14 -14
  61. package/build/lib-common/async-cryptor-wrap.d.ts +9 -9
  62. package/build/lib-common/async-cryptor-wrap.js +13 -13
  63. package/build/lib-common/byte-streaming/pipe.d.ts +1 -1
  64. package/build/lib-common/byte-streaming/pipe.js +3 -3
  65. package/build/lib-common/byte-streaming/wrapping.js +4 -2
  66. package/build/lib-common/json-utils.js +0 -3
  67. package/build/lib-common/processes/synced.js +0 -184
  68. package/build/lib-sqlite-on-3nstorage/index.d.ts +32 -0
  69. package/build/lib-sqlite-on-3nstorage/index.js +117 -0
  70. package/build/lib-sqlite-on-3nstorage/sqljs.d.ts +279 -0
  71. package/build/lib-sqlite-on-3nstorage/sqljs.js +223 -0
  72. package/build/protos/asmail.proto.js +3748 -1121
  73. package/build/protos/bytes.proto.js +731 -204
  74. package/build/protos/common.proto.js +192 -44
  75. package/build/protos/cryptor.proto.js +184 -61
  76. package/build/protos/file.proto.js +1336 -324
  77. package/build/protos/fs.proto.js +3099 -846
  78. package/build/protos/ipc.proto.js +244 -61
  79. package/build/protos/logger.proto.js +219 -53
  80. package/build/protos/mailerid.proto.js +230 -50
  81. package/build/protos/startup.proto.js +341 -77
  82. package/build/protos/storage.proto.js +276 -62
  83. package/package.json +8 -7
  84. package/protos/bytes.proto +13 -4
  85. package/protos/file.proto +4 -1
  86. package/protos/fs.proto +4 -1
@@ -44,6 +44,7 @@ declare namespace web3n.files {
44
44
  versionMismatch?: true;
45
45
  isEndless?: true;
46
46
  storageClosed?: true;
47
+ remoteNotSet?: true;
47
48
  }
48
49
 
49
50
  interface exceptionCode {
@@ -192,7 +193,17 @@ declare namespace web3n.files {
192
193
  * @param len maximum number of bytes to read from file. If undefine is
193
194
  * given, all bytes are read from current postion to the end of file.
194
195
  */
195
- read(len: number|undefined): Promise<Uint8Array|undefined>;
196
+ readNext(len: number|undefined): Promise<Uint8Array|undefined>;
197
+
198
+ /**
199
+ * This moves current position to a given value and read given number of
200
+ * bytes. It is equivalent to calling seek() and readNext() with
201
+ * respective arguments.
202
+ * @param pos is a position at which to start read.
203
+ * @param len maximum number of bytes to read from file. If undefine is
204
+ * given, all bytes are read from current postion to the end of file.
205
+ */
206
+ readAt(pos: number, len: number|undefined): Promise<Uint8Array|undefined>;
196
207
 
197
208
  /**
198
209
  * This returns a promise, resolvable to the size of this file.
@@ -264,7 +275,8 @@ declare namespace web3n.files {
264
275
  * sink with this error. When err is given, no errors will be thrown back
265
276
  * to this call.
266
277
  */
267
- done(err?: any): Promise<void>;
278
+ done(err?: any, xattrChanges?: XAttrsChanges): Promise<void>;
279
+
268
280
  }
269
281
 
270
282
  type Linkable = File | FS;
@@ -382,20 +394,28 @@ declare namespace web3n.files {
382
394
  /**
383
395
  * This returns a promise, resolvable when file is written
384
396
  * @param bytes is a complete file content to write
397
+ * @param xattrChanges is optional changes to xattrs, to pack them in the
398
+ * same go
385
399
  */
386
- writeBytes(bytes: Uint8Array): Promise<void>;
400
+ writeBytes(
401
+ bytes: Uint8Array, xattrChanges?: XAttrsChanges
402
+ ): Promise<void>;
387
403
 
388
404
  /**
389
405
  * This returns a promise, resolvable when file is written
390
406
  * @param txt to write to file, using utf8 encoding
407
+ * @param xattrChanges is optional changes to xattrs, to pack them in the
408
+ * same go
391
409
  */
392
- writeTxt(txt: string): Promise<void>;
410
+ writeTxt(txt: string, xattrChanges?: XAttrsChanges): Promise<void>;
393
411
 
394
412
  /**
395
413
  * This returns a promise, resolvable when file is written
396
414
  * @param json
415
+ * @param xattrChanges is optional changes to xattrs, to pack them in the
416
+ * same go
397
417
  */
398
- writeJSON(json: any): Promise<void>;
418
+ writeJSON(json: any, xattrChanges?: XAttrsChanges): Promise<void>;
399
419
 
400
420
  /**
401
421
  * This returns a promise, resolvable to byte sink with seek
@@ -495,22 +515,30 @@ declare namespace web3n.files {
495
515
  * This returns a promise, resolvable to new file's version when file is
496
516
  * written
497
517
  * @param bytes is a complete file content to write
518
+ * @param xattrChanges is optional changes to xattrs, to pack them into
519
+ * the same file version
498
520
  */
499
- writeBytes(bytes: Uint8Array): Promise<number>;
521
+ writeBytes(
522
+ bytes: Uint8Array, xattrChanges?: XAttrsChanges
523
+ ): Promise<number>;
500
524
 
501
525
  /**
502
526
  * This returns a promise, resolvable to new file's version when file is
503
527
  * written
504
528
  * @param txt to write to file, using utf8 encoding
529
+ * @param xattrChanges is optional changes to xattrs, to pack them into
530
+ * the same file version
505
531
  */
506
- writeTxt(txt: string): Promise<number>;
532
+ writeTxt(txt: string, xattrChanges?: XAttrsChanges): Promise<number>;
507
533
 
508
534
  /**
509
535
  * This returns a promise, resolvable to new file's version when file is
510
536
  * written
511
537
  * @param json
538
+ * @param xattrChanges is optional changes to xattrs, to pack them into
539
+ * the same file version
512
540
  */
513
- writeJSON(json: any): Promise<number>;
541
+ writeJSON(json: any, xattrChanges?: XAttrsChanges): Promise<number>;
514
542
 
515
543
  /**
516
544
  * This returns a promise, resolvable to byte sink with seek, and a file
@@ -567,7 +595,7 @@ declare namespace web3n.files {
567
595
 
568
596
  interface WritableFileSyncAPI extends ReadonlyFileSyncAPI {
569
597
 
570
- upload(opts?: OptionsToUploadLocal): Promise<void>;
598
+ upload(opts?: OptionsToUploadLocal): Promise<number|undefined>;
571
599
 
572
600
  }
573
601
 
@@ -1191,7 +1219,9 @@ declare namespace web3n.files {
1191
1219
 
1192
1220
  interface WritableFSSyncAPI extends ReadonlyFSSyncAPI {
1193
1221
 
1194
- upload(path: string, opts?: OptionsToUploadLocal): Promise<void>;
1222
+ upload(
1223
+ path: string, opts?: OptionsToUploadLocal
1224
+ ): Promise<number|undefined>;
1195
1225
 
1196
1226
  adoptRemoteFolderItem(
1197
1227
  path: string, itemName: string, opts?: OptionsToAdoptRemoteItem
@@ -370,7 +370,7 @@ class WIP {
370
370
  if (!isEndless) {
371
371
  obj.upload.expectedSegsSize = size;
372
372
  }
373
- let segsChunk = await obj.src.segSrc.read(this.sender.maxChunkSize - header.length);
373
+ let segsChunk = await obj.src.segSrc.readNext(this.sender.maxChunkSize - header.length);
374
374
  // check if we'll be done in this request
375
375
  const segsSize = obj.upload.expectedSegsSize;
376
376
  let isObjDone = false;
@@ -406,7 +406,7 @@ class WIP {
406
406
  async followingObjSendingRequest(obj) {
407
407
  // read from source
408
408
  const segsSize = obj.upload.expectedSegsSize;
409
- const chunk = await obj.src.segSrc.read(this.sender.maxChunkSize);
409
+ const chunk = await obj.src.segSrc.readNext(this.sender.maxChunkSize);
410
410
  // return early, when there are no bytes
411
411
  if (!chunk) {
412
412
  await this.sender.sendObj(obj.objId, EMPTY_BYTE_ARR, undefined, { ofs: obj.upload.segsOffset, last: true });
@@ -30,11 +30,16 @@ class InboxEvents {
30
30
  constructor(msgReceiver, getMsg, logError) {
31
31
  const serverEvents = new server_events_1.ServerEvents(() => msgReceiver.openEventSource(), SERVER_EVENTS_RESTART_WAIT_SECS);
32
32
  this.newMsg$ = serverEvents.observe(retrieval_1.msgRecievedCompletely.EVENT_NAME)
33
- .pipe((0, operators_1.mergeMap)(ev => getMsg(ev.msgId)
34
- .catch(async (err) => {
35
- // TODO should more error handling logic be added here?
36
- await logError(err, `Cannot get message ${ev.msgId}`);
37
- })), (0, operators_1.filter)(msg => !!msg), (0, operators_1.share)());
33
+ .pipe((0, operators_1.mergeMap)(async (ev) => {
34
+ try {
35
+ const msg = await getMsg(ev.msgId);
36
+ return msg;
37
+ }
38
+ catch (err) {
39
+ // TODO should more error handling logic be added here?
40
+ await logError(err, `Cannot get message ${ev.msgId}`);
41
+ }
42
+ }), (0, operators_1.filter)(msg => !!msg), (0, operators_1.share)());
38
43
  Object.seal(this);
39
44
  }
40
45
  subscribe(event, observer) {
@@ -38,7 +38,7 @@ export interface ResourcesForReceiving {
38
38
  * object.
39
39
  * @param checkMidKeyCerts is a certifying function for MailerId certs.
40
40
  */
41
- msgDecryptor: (msgMeta: delivApi.msgMeta.CryptoInfo, getMainObjHeader: () => Promise<Uint8Array>, getOpenedMsg: (mainObjFileKey: string, msgKeyPackLen: number) => Promise<OpenedMsg>, checkMidKeyCerts: (certs: confApi.p.initPubKey.Certs) => Promise<{
41
+ msgDecryptor: (msgMeta: delivApi.msgMeta.CryptoInfo, getMainObjHeader: () => Promise<Uint8Array>, getOpenedMsg: (mainObjFileKey: Uint8Array, msgKeyPackLen: number) => Promise<OpenedMsg>, checkMidKeyCerts: (certs: confApi.p.initPubKey.Certs) => Promise<{
42
42
  pkey: JsonKey;
43
43
  address: string;
44
44
  }>) => Promise<{
@@ -83,7 +83,8 @@ export declare class InboxOnServer {
83
83
  private readonly procs;
84
84
  private readonly recentlyOpenedMsgs;
85
85
  private constructor();
86
- static makeAndStart(cachePath: string, fs: WritableFS, r: ResourcesForReceiving): Promise<InboxOnServer>;
86
+ static makeAndStart(cachePath: string, syncedFS: WritableFS, r: ResourcesForReceiving): Promise<InboxOnServer>;
87
+ close(): Promise<void>;
87
88
  wrap(): InboxService;
88
89
  private removeMsg;
89
90
  private removeMsgFromServerAndCache;
@@ -24,13 +24,14 @@ const opener_1 = require("../msg/opener");
24
24
  const msg_indexing_1 = require("./msg-indexing");
25
25
  const fs_1 = require("./attachments/fs");
26
26
  const canonical_address_1 = require("../../../lib-common/canonical-address");
27
- const buffer_utils_1 = require("../../../lib-common/buffer-utils");
28
27
  const key_verification_1 = require("../key-verification");
29
28
  const inbox_events_1 = require("./inbox-events");
30
29
  const file_1 = require("../../../lib-common/exceptions/file");
31
30
  const msg_downloader_1 = require("./msg-downloader");
32
31
  const cached_msgs_1 = require("./cached-msgs");
33
32
  const timed_cache_1 = require("../../../lib-common/timed-cache");
33
+ const fs_sync_utils_1 = require("../../../lib-client/fs-sync-utils");
34
+ const MSG_INDEX_FOLDER = 'msg-index';
34
35
  /**
35
36
  * Instance of this class represents inbox-on-mail-server.
36
37
  * It uses api to manage messages on a ASMail server, caching and recording
@@ -53,19 +54,24 @@ class InboxOnServer {
53
54
  this.inboxEvents = new inbox_events_1.InboxEvents(this.msgReceiver, this.getMsg.bind(this), this.logError);
54
55
  Object.seal(this);
55
56
  }
56
- static async makeAndStart(cachePath, fs, r) {
57
+ static async makeAndStart(cachePath, syncedFS, r) {
57
58
  try {
58
- (0, file_1.ensureCorrectFS)(fs, 'synced', true);
59
+ (0, file_1.ensureCorrectFS)(syncedFS, 'synced', true);
59
60
  const msgReceiver = new recipient_1.MailRecipient(r.address, r.getSigner, () => r.asmailResolver(r.address), r.makeNet());
60
61
  const downloader = new msg_downloader_1.MsgDownloader(msgReceiver);
61
62
  const cache = await cached_msgs_1.CachedMessages.makeFor(cachePath, downloader, r.logError);
62
- const index = await msg_indexing_1.MsgIndex.makeWith(fs);
63
+ const indexSyncedFS = await (0, fs_sync_utils_1.getOrMakeAndUploadFolderIn)(syncedFS, MSG_INDEX_FOLDER);
64
+ const index = await msg_indexing_1.MsgIndex.make(indexSyncedFS);
65
+ await (0, fs_sync_utils_1.uploadFolderChangesIfAny)(syncedFS);
63
66
  return new InboxOnServer(r.correspondents, msgReceiver, r.getStorages, r.cryptor, downloader, cache, index, r.logError);
64
67
  }
65
68
  catch (err) {
66
69
  throw (0, error_1.errWithCause)(err, 'Failed to initialize Inbox');
67
70
  }
68
71
  }
72
+ async close() {
73
+ this.index.stopSyncing();
74
+ }
69
75
  wrap() {
70
76
  const service = {
71
77
  getMsg: this.getMsg.bind(this),
@@ -85,7 +91,7 @@ class InboxOnServer {
85
91
  // start removal process
86
92
  return this.procs.start(procId, (async () => {
87
93
  await Promise.all([
88
- this.index.removeUsingIdOnly(msgId),
94
+ this.index.remove(msgId),
89
95
  this.removeMsgFromServerAndCache(msgId)
90
96
  ]);
91
97
  }));
@@ -121,9 +127,7 @@ class InboxOnServer {
121
127
  if (!mainObjSrc) {
122
128
  mainObjSrc = await msgOnDisk.getMsgObj(mainObjId);
123
129
  }
124
- const fKey = buffer_utils_1.base64.open(mainObjFileKey);
125
- const openedMsg = await (0, opener_1.openMsg)(msgId, mainObjId, mainObjSrc, msgKeyPackLen, fKey, this.cryptor);
126
- fKey.fill(0);
130
+ const openedMsg = await (0, opener_1.openMsg)(msgId, mainObjId, mainObjSrc, msgKeyPackLen, mainObjFileKey, this.cryptor);
127
131
  return openedMsg;
128
132
  };
129
133
  const checkMidKeyCerts = (certs) => {
@@ -149,7 +153,7 @@ class InboxOnServer {
149
153
  }
150
154
  else {
151
155
  // check, if msg has already been indexed
152
- const knownDecr = await this.index.fKeyFor({ msgId, deliveryTS: msgOnDisk.deliveryTS });
156
+ const knownDecr = await this.index.getKeyFor(msgId, msgOnDisk.deliveryTS);
153
157
  if (!knownDecr) {
154
158
  await msgOnDisk.updateMsgKeyStatus('not-found');
155
159
  return false;
@@ -263,7 +267,7 @@ class InboxOnServer {
263
267
  const meta = await msgOnDisk.getMsgMeta();
264
268
  const mainObjId = meta.extMeta.objIds[0];
265
269
  const mainObj = await msgOnDisk.getMsgObj(mainObjId);
266
- const msgKey = await this.index.fKeyFor({ msgId, deliveryTS: meta.deliveryCompletion });
270
+ const msgKey = await this.index.getKeyFor(msgId, meta.deliveryCompletion);
267
271
  if (!msgKey) {
268
272
  throw (0, recipient_1.makeMsgNotFoundException)(msgId);
269
273
  }
@@ -1,76 +1,29 @@
1
1
  import { MsgKeyInfo, MsgKeyRole } from '../keyring';
2
2
  declare type WritableFS = web3n.files.WritableFS;
3
- interface MsgInfoWithoutType {
4
- msgId: string;
5
- deliveryTS: number;
6
- }
3
+ declare type MsgInfo = web3n.asmail.MsgInfo;
7
4
  /**
8
- * This message index stores MsgRecord's for message present on the server, i.e.
5
+ * This message index stores info for messages present on the server, in the
9
6
  * inbox. Records contain message key info, time of delivery, and time of
10
- * desired removal. Note that when user wants to keep a particular message for
11
- * a long time, it should be copied elsewhere, and not kept in the asmail
12
- * server inbox. Therefore, this index has to deal only with more-or-less
13
- * recent messages.
7
+ * desired removal.
14
8
  *
15
- * This implementation is not using database for records, but a log-like files.
16
- * Latest file is appended to certain length, and then is left to a mostly-read
17
- * existence, carrying messages' info till message removal.
18
- * When lookup is done only with message id, all files potentially need to be
19
- * read. When both message id and delivery timestamp are given, lookup will at
20
- * most touch two-three files.
9
+ * Message info with keys is stored in SQLite dbs sharded/partitioned by
10
+ * delivery timestamp. The latest shard, shard without upper time limit
11
+ * is stored in local storage, while all other shards with limits are stored in
12
+ * synced storage. Information in synced storage is a sum of all limited shards
13
+ * and action logs. Action logs
21
14
  *
22
15
  */
23
16
  export declare class MsgIndex {
24
- private files;
25
- private latest;
26
- private readonly cached;
27
- private fileTSs;
28
- private readonly fileProc;
17
+ private readonly files;
18
+ private readonly records;
19
+ private readonly changes;
29
20
  private constructor();
30
- static makeWith(files: WritableFS): Promise<MsgIndex>;
31
- /**
32
- * @param recs that need to be saved
33
- * @return a promise, resolvable when given records are saved. Latest
34
- * records can also be chunked and saved as needed.
35
- */
36
- private saveRecords;
37
- /**
38
- * @param fileTS is index file's timestamp. Undefined value means latest
39
- * records.
40
- * @return a promise, resolvable to found records, either from a memory
41
- * cache, or from a file.
42
- */
43
- private getRecords;
44
- /**
45
- * @param msgInfo is a minimal message info object
46
- * @param decrInfo
47
- * @return a promise, resolvable when given message info bits are recorded.
48
- */
49
- add(msgInfo: web3n.asmail.MsgInfo, decrInfo: MsgKeyInfo): Promise<void>;
50
- private findRecordsWith;
51
- /**
52
- * @param msg is a message identifying info used to find and remove message
53
- * @return a promise, resolvable when message is removed from this index.
54
- */
55
- remove(msg: MsgInfoWithoutType): Promise<void>;
56
- /**
57
- * @param msg is an id of a message to remove
58
- * @return a promise, resolvable when message is removed from this index.
59
- */
60
- removeUsingIdOnly(msgId: string): Promise<void>;
61
- /**
62
- * @param fromTS
63
- * @return a promise, resolvable to an ordered array of MsgInfo's that have
64
- * delivery timestamp same or later, than the given one.
65
- */
66
- listMsgs(fromTS: number | undefined): Promise<web3n.asmail.MsgInfo[]>;
67
- /**
68
- * This returns a promise resolvable to message's file key holder and key
69
- * role, when message is found, and resolvabel to an undefined, when message
70
- * is not known.
71
- * @param msg is a message identifying info used to find message
72
- */
73
- fKeyFor(msg: MsgInfoWithoutType): Promise<{
21
+ static make(syncedFS: WritableFS): Promise<MsgIndex>;
22
+ stopSyncing(): void;
23
+ add(msgInfo: MsgInfo, decrInfo: MsgKeyInfo, removeAfter?: number): Promise<void>;
24
+ remove(msgId: string): Promise<void>;
25
+ listMsgs(fromTS: number | undefined): Promise<MsgInfo[]>;
26
+ getKeyFor(msgId: string, deliveryTS: number): Promise<{
74
27
  msgKey: Uint8Array;
75
28
  msgKeyRole: MsgKeyRole;
76
29
  mainObjHeaderOfs: number;