core-3nweb-client-lib 0.49.7 → 0.50.0

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 (44) hide show
  1. package/build/api-defs/asmail.d.ts +1 -0
  2. package/build/api-defs/files.d.ts +1 -1
  3. package/build/core/asmail/delivery/per-recipient-wip.js +4 -0
  4. package/build/core/asmail/inbox/index.d.ts +8 -31
  5. package/build/core/asmail/inbox/index.js +119 -164
  6. package/build/core/asmail/inbox/msg-indexing/index.js +8 -9
  7. package/build/core/asmail/inbox/msg-on-disk.d.ts +0 -5
  8. package/build/core/asmail/inbox/msg-on-disk.js +1 -22
  9. package/build/core/asmail/index.js +4 -4
  10. package/build/core/asmail/sending-params/index.d.ts +13 -14
  11. package/build/core/asmail/sending-params/index.js +15 -35
  12. package/build/core/asmail/sending-params/invitations-anon.d.ts +7 -31
  13. package/build/core/asmail/sending-params/invitations-anon.js +77 -127
  14. package/build/core/asmail/sending-params/own-params.d.ts +5 -25
  15. package/build/core/asmail/sending-params/own-params.js +144 -97
  16. package/build/core/asmail/sending-params/params-from-others.d.ts +6 -16
  17. package/build/core/asmail/sending-params/params-from-others.js +88 -58
  18. package/build/core/index.d.ts +2 -1
  19. package/build/core/index.js +4 -4
  20. package/build/core/keyring/index.js +2 -3
  21. package/build/core/keyring/introductory-keys/published-intro-key.d.ts +2 -2
  22. package/build/core/keyring/introductory-keys/published-intro-key.js +71 -71
  23. package/build/core/keyring/peer-keys/index.js +6 -7
  24. package/build/core/storage/index.d.ts +2 -1
  25. package/build/core/storage/index.js +4 -3
  26. package/build/core/storage/system-folders/index.d.ts +1 -2
  27. package/build/core/storage/system-folders/index.js +18 -22
  28. package/build/lib-client/asmail/recipient.d.ts +1 -0
  29. package/build/lib-client/asmail/recipient.js +11 -0
  30. package/build/lib-client/fs-utils/fs-sync-utils.d.ts +1 -1
  31. package/build/lib-client/fs-utils/fs-sync-utils.js +21 -15
  32. package/build/lib-client/xsp-fs/folder-node.js +13 -3
  33. package/build/lib-client/xsp-fs/util/file-based-json.js +1 -1
  34. package/build/lib-common/dataset-sync/per-device-json-array-logs.js +43 -28
  35. package/build/lib-common/dataset-sync/single-file.d.ts +12 -0
  36. package/build/lib-common/dataset-sync/single-file.js +73 -0
  37. package/build/lib-common/dataset-sync/utils.d.ts +16 -0
  38. package/build/lib-common/dataset-sync/utils.js +72 -0
  39. package/build/lib-common-on-node/device-fs-places.d.ts +3 -0
  40. package/build/{lib-client/xsp-fs/util/for-arrays.js → lib-common-on-node/device-fs-places.js} +21 -13
  41. package/build/tests/computer.3nweb.core/keyrings.js +2 -2
  42. package/build/tests/libs-for-tests/core-runner.js +2 -1
  43. package/package.json +1 -1
  44. package/build/lib-client/xsp-fs/util/for-arrays.d.ts +0 -1
@@ -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.makeFailToDecryptMsgException = makeFailToDecryptMsgException;
21
22
  exports.makeObjNotFoundException = makeObjNotFoundException;
22
23
  exports.makeMsgIsBrokenException = makeMsgIsBrokenException;
23
24
  const request_utils_1 = require("../request-utils");
@@ -37,6 +38,16 @@ function makeMsgNotFoundException(msgId) {
37
38
  };
38
39
  return exc;
39
40
  }
41
+ function makeFailToDecryptMsgException(msgId) {
42
+ const exc = {
43
+ runtimeException: true,
44
+ type: 'inbox',
45
+ msgId,
46
+ failToDecrypt: true,
47
+ stack: (0, runtime_1.getStackHere)(1)
48
+ };
49
+ return exc;
50
+ }
40
51
  function makeObjNotFoundException(msgId, objId) {
41
52
  const exc = {
42
53
  runtimeException: true,
@@ -5,7 +5,7 @@ type RemoteEvent = web3n.files.RemoteEvent;
5
5
  type FileEvent = web3n.files.FileEvent;
6
6
  type FolderEvent = web3n.files.FolderEvent;
7
7
  export declare function getRemoteFolderChanges(fs: WritableFS): Promise<void>;
8
- export declare function getOrMakeSyncedDirOnInit(syncedFS: WritableFS, dir: string): Promise<WritableFS>;
8
+ export declare function getOrMakeDirOnInit(syncedFS: WritableFS, dir: string): Promise<WritableFS>;
9
9
  export declare function uploadFolderChangesIfAny(fs: WritableFS): Promise<void>;
10
10
  export declare function observableFromTreeEvents(fs: ReadonlyFS, rootPath: string): Observable<RemoteEvent | FileEvent | FolderEvent>;
11
11
  export {};
@@ -17,12 +17,11 @@
17
17
  */
18
18
  Object.defineProperty(exports, "__esModule", { value: true });
19
19
  exports.getRemoteFolderChanges = getRemoteFolderChanges;
20
- exports.getOrMakeSyncedDirOnInit = getOrMakeSyncedDirOnInit;
20
+ exports.getOrMakeDirOnInit = getOrMakeDirOnInit;
21
21
  exports.uploadFolderChangesIfAny = uploadFolderChangesIfAny;
22
22
  exports.observableFromTreeEvents = observableFromTreeEvents;
23
23
  const rxjs_1 = require("rxjs");
24
24
  const exceptions_1 = require("../xsp-fs/exceptions");
25
- const assert_1 = require("../../lib-common/assert");
26
25
  async function getRemoteFolderChanges(fs) {
27
26
  let { state } = await fs.v.sync.status('');
28
27
  if (state === 'behind') {
@@ -36,13 +35,16 @@ async function getRemoteFolderChanges(fs) {
36
35
  });
37
36
  }
38
37
  }
39
- async function getOrMakeSyncedDirOnInit(syncedFS, dir) {
38
+ async function getOrMakeDirOnInit(syncedFS, dir) {
40
39
  // Except for initial time, all folders exist and synced into parent, so, we shortcut sync check, if dir exists.
41
40
  // This allows to start while offline, when initialization has been done.
42
41
  if (await syncedFS.checkFolderPresence(dir)) {
43
42
  return await syncedFS.writableSubRoot(dir, { create: false });
44
43
  }
45
- await ensureIsInSyncedState(syncedFS);
44
+ await attemptToBringToSyncedState(syncedFS)
45
+ .catch(exc => {
46
+ console.error(`\n ------`, dir, exc);
47
+ });
46
48
  if (await syncedFS.checkFolderPresence(dir)) {
47
49
  return await syncedFS.writableSubRoot(dir, { create: false });
48
50
  }
@@ -58,15 +60,10 @@ async function getOrMakeSyncedDirOnInit(syncedFS, dir) {
58
60
  }
59
61
  }
60
62
  function noop() { }
61
- async function ensureIsInSyncedState(syncedFS) {
63
+ async function attemptToBringToSyncedState(syncedFS) {
62
64
  const { existsInSyncedParent, state, remote } = await syncedFS.v.sync.status('');
63
- // assert(!!existsInSyncedParent, `${syncedFS.name} is not present in synced parent, preventing further construction of synced fs tree`);
64
- if (state === 'synced') {
65
- return;
66
- }
67
- else if (state === 'behind') {
65
+ if (state === 'behind') {
68
66
  await syncedFS.v.sync.adoptRemote('.');
69
- return;
70
67
  }
71
68
  else if (state === 'unsynced') {
72
69
  await syncedFS.v.sync.upload('.').catch(async (exc) => {
@@ -77,11 +74,20 @@ async function ensureIsInSyncedState(syncedFS) {
77
74
  await recursivelyUploadNewTreeItems(syncedFS, '.');
78
75
  }
79
76
  });
80
- return;
81
77
  }
82
- (0, assert_1.assert)(state !== 'conflicting');
78
+ else if (state === 'conflicting') {
79
+ await syncedFS.v.sync.absorbRemoteFolderChanges('.');
80
+ await syncedFS.v.sync.upload('.', { uploadVersion: remote.latest }).catch(async (exc) => {
81
+ if (exc.type !== 'fs-sync') {
82
+ throw exc;
83
+ }
84
+ else if (exc.childNeverUploaded) {
85
+ await recursivelyUploadNewTreeItems(syncedFS, '.', remote.latest);
86
+ }
87
+ });
88
+ }
83
89
  }
84
- async function recursivelyUploadNewTreeItems(fs, path) {
90
+ async function recursivelyUploadNewTreeItems(fs, path, uploadVersion) {
85
91
  for (const item of await fs.listFolder(path)) {
86
92
  const { remote, synced } = await fs.v.sync.status(`${path}/${item.name}`);
87
93
  if (remote || synced) {
@@ -92,7 +98,7 @@ async function recursivelyUploadNewTreeItems(fs, path) {
92
98
  }
93
99
  await fs.v.sync.upload(`${path}/${item.name}`);
94
100
  }
95
- await fs.v.sync.upload(path);
101
+ await fs.v.sync.upload(path, { uploadVersion });
96
102
  }
97
103
  // export async function getOrMakeAndUploadFolderIn(fs: WritableFS, folder: string): Promise<WritableFS> {
98
104
  // try {
@@ -36,7 +36,6 @@ const folder_node_serialization_1 = require("./folder-node-serialization");
36
36
  const attrs_1 = require("./attrs");
37
37
  const node_persistence_1 = require("./node-persistence");
38
38
  const assert_1 = require("../../lib-common/assert");
39
- const for_arrays_1 = require("./util/for-arrays");
40
39
  function jsonToInfoAndAttrs(json) {
41
40
  const folderInfo = {
42
41
  nodes: (0, json_utils_1.copy)(json.nodes)
@@ -870,7 +869,7 @@ class FolderNode extends node_in_fs_1.NodeInFS {
870
869
  async uploadRemovalOf(removedNodes) {
871
870
  const rmObjs = [];
872
871
  for (const node of removedNodes) {
873
- (0, for_arrays_1.appendArray)(rmObjs, await this.listRemovedInTreeToUploadRm(node));
872
+ appendArray(rmObjs, await this.listRemovedInTreeToUploadRm(node));
874
873
  }
875
874
  await this.uploadRemovalOfObjs(rmObjs);
876
875
  }
@@ -896,7 +895,7 @@ class FolderNode extends node_in_fs_1.NodeInFS {
896
895
  const src = await storage.getObjSrc(node.objId, versionBeforeRm, true);
897
896
  const folderContent = await FolderPersistance.readFolderContent(node.objId, node.key, src, storage.cryptor, storage.random);
898
897
  for (const child of Object.values(folderContent.nodes)) {
899
- (0, for_arrays_1.appendArray)(objs, await this.listRemovedInTreeToUploadRm(child));
898
+ appendArray(objs, await this.listRemovedInTreeToUploadRm(child));
900
899
  }
901
900
  return objs;
902
901
  }
@@ -1136,6 +1135,17 @@ class FolderNode extends node_in_fs_1.NodeInFS {
1136
1135
  exports.FolderNode = FolderNode;
1137
1136
  Object.freeze(FolderNode.prototype);
1138
1137
  Object.freeze(FolderNode);
1138
+ function appendArray(arr, elems) {
1139
+ if (elems !== undefined) {
1140
+ if (Array.isArray(elems)) {
1141
+ arr.push(...elems);
1142
+ }
1143
+ else {
1144
+ arr.push(elems);
1145
+ }
1146
+ }
1147
+ return arr;
1148
+ }
1139
1149
  const EMPTY_ARR = new Uint8Array(0);
1140
1150
  function noop() { }
1141
1151
  function checkFolderInfo(folderJson) {
@@ -20,7 +20,7 @@ exports.JsonFileProc = void 0;
20
20
  const rxjs_1 = require("rxjs");
21
21
  const operators_1 = require("rxjs/operators");
22
22
  const synced_1 = require("../../../lib-common/processes/synced");
23
- // XXX File proc can have general flow for sync
23
+ // XXX File proc can have general flow for sync, missing now!
24
24
  class JsonFileProc {
25
25
  constructor(onFileEvent, order = new synced_1.SingleProc()) {
26
26
  this.onFileEvent = onFileEvent;
@@ -21,7 +21,6 @@ exports.startDatasetSync = startDatasetSync;
21
21
  const synced_1 = require("../processes/synced");
22
22
  const buffer_utils_1 = require("../buffer-utils");
23
23
  const rng_def_1 = require("../rng-def");
24
- const sink_utils_1 = require("../obj-streaming/sink-utils");
25
24
  const DEVICE_ID_FILE = 'device-id';
26
25
  const DEV_LOGS_PROCESSING_FILE = 'dev-logs-processing';
27
26
  const DEV_ID_LEN = 24;
@@ -122,11 +121,11 @@ async function makeRecentChangesLogs(logsFS, localLogsFS, areOpsEqual, logError)
122
121
  return;
123
122
  }
124
123
  try {
125
- const content = (await logsFS.readBytes(logFile));
124
+ const content = (await logsFS.readTxtFile(logFile));
126
125
  if (!content) {
127
126
  return;
128
127
  }
129
- const appendedEvents = deserializeLogs(buffer_utils_1.utf8.open(content));
128
+ const appendedEvents = deserializeLogs(content);
130
129
  processFromLogFile(devId, appendedEvents, sink);
131
130
  }
132
131
  catch (err) {
@@ -211,28 +210,37 @@ async function makeRecentChangesLogs(logsFS, localLogsFS, areOpsEqual, logError)
211
210
  async function saveAndUploadIfNeeded() {
212
211
  if (needToSave && (logs.length > numOfEntriesOnLastSave)) {
213
212
  needToSave = false;
214
- if (numOfEntriesOnLastSave > 0) {
215
- const logsToAppend = logs.slice(numOfEntriesOnLastSave);
216
- const logsTxt = serializeLogs(logsToAppend);
217
- const sink = await thisDevLogsFile.getByteSink(false);
218
- try {
219
- await (0, sink_utils_1.appendFiniteSink)(sink, buffer_utils_1.utf8.pack(','), false);
220
- await (0, sink_utils_1.appendFiniteSink)(sink, buffer_utils_1.utf8.pack(logsTxt), true);
221
- }
222
- catch (err) {
223
- await sink.done(err);
224
- }
225
- numOfEntriesOnLastSave += logsToAppend.length;
226
- }
227
- else {
228
- const logsTxt = serializeLogs(logs);
229
- const numOfLogs = logs.length;
230
- await thisDevLogsFile.writeTxt(logsTxt)
231
- .catch(_exc => {
232
- needToSave = true;
233
- });
234
- numOfEntriesOnLastSave += numOfLogs;
235
- }
213
+ // XXX do more efficient appending
214
+ // sink.slice is not doing efficient appending job, and when versions go into 1000's it blows things up.
215
+ // When appending can be done properly, we can switch to a more efficient
216
+ //
217
+ // if (numOfEntriesOnLastSave > 0) {
218
+ // const logsToAppend = logs.slice(numOfEntriesOnLastSave);
219
+ // const logsTxt = serializeLogs(logsToAppend);
220
+ // const sink = await thisDevLogsFile.getByteSink(false);
221
+ // try {
222
+ // await appendFiniteSink(sink, utf8.pack(','), false);
223
+ // await appendFiniteSink(sink, utf8.pack(logsTxt), true);
224
+ // } catch (err) {
225
+ // await sink.done(err);
226
+ // }
227
+ // numOfEntriesOnLastSave += logsToAppend.length;
228
+ // } else {
229
+ // const logsTxt = serializeLogs(logs);
230
+ // const numOfLogs = logs.length
231
+ // await thisDevLogsFile.writeTxt(logsTxt)
232
+ // .catch(_exc => {
233
+ // needToSave = true;
234
+ // });
235
+ // numOfEntriesOnLastSave = numOfLogs;
236
+ // }
237
+ const logsTxt = serializeLogs(logs);
238
+ const numOfLogs = logs.length;
239
+ await thisDevLogsFile.writeTxt(logsTxt)
240
+ .catch(_exc => {
241
+ needToSave = true;
242
+ });
243
+ numOfEntriesOnLastSave = numOfLogs;
236
244
  needToUpload = true;
237
245
  }
238
246
  if (needToUpload) {
@@ -298,7 +306,13 @@ async function makeRecentChangesLogs(logsFS, localLogsFS, areOpsEqual, logError)
298
306
  await logsFS.v.sync.upload('');
299
307
  }
300
308
  else if (state === 'unsynced') {
301
- await logsFS.v.sync.upload('');
309
+ await logsFS.v.sync.upload('')
310
+ .catch(async (exc) => {
311
+ if (exc.childNeverUploaded) {
312
+ await localLogsFS.deleteFile(exc.childName);
313
+ return syncLogsFS();
314
+ }
315
+ });
302
316
  }
303
317
  }
304
318
  return {
@@ -403,15 +417,16 @@ function startDatasetSync(periodicCheckAndUploadOfData, millisBeforeNextRun, log
403
417
  // We pass this single process point out to wrap fn's with it, in an attempt to explicitly keeping it at the
404
418
  // boundary of incoming operations, either from fn calls, or from handling changes passed via fs events.
405
419
  const changeProc = new synced_1.SingleProc();
406
- function dbSyncCheckAndAction() {
420
+ function datasetCheckAndSyncAction() {
407
421
  changeProc.startOrChain(periodicCheckAndUploadOfData);
408
422
  }
409
423
  let interval = undefined;
410
424
  function resetSyncInterval() {
425
+ var _a, _b;
411
426
  if (interval !== undefined) {
412
427
  clearInterval(interval);
413
428
  }
414
- interval = setInterval(dbSyncCheckAndAction, millisBeforeNextRun()).unref();
429
+ interval = (_b = (_a = setInterval(datasetCheckAndSyncAction, millisBeforeNextRun())).unref) === null || _b === void 0 ? void 0 : _b.call(_a);
415
430
  }
416
431
  resetSyncInterval();
417
432
  // XXX we should watch for reconnect events and run similar to start checks of possibly missed ops
@@ -0,0 +1,12 @@
1
+ import { SingleProc } from "../processes/synced";
2
+ type WritableFS = web3n.files.WritableFS;
3
+ type WritableFile = web3n.files.WritableFile;
4
+ export declare function initSyncedFile(syncedFS: WritableFS, fName: string, initNewFile: (newFile: WritableFile) => Promise<void>): Promise<{
5
+ file: WritableFile;
6
+ changeProc: SingleProc;
7
+ }>;
8
+ export declare function watchAndApplyChangesFromOtherDevices(file: WritableFile, changeProc: SingleProc, onChangeFromOtherDevices: (fileVersion: number, changeProc: SingleProc, file: WritableFile) => Promise<void>, onConflictingChangeFromOtherDevices: (changeProc: SingleProc, file: WritableFile) => Promise<void>): {
9
+ stopFileWatching: () => void;
10
+ triggerUpload: () => void;
11
+ };
12
+ export {};
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ /*
3
+ Copyright (C) 2026 3NSoft Inc.
4
+
5
+ This program is free software: you can redistribute it and/or modify it under
6
+ the terms of the GNU General Public License as published by the Free Software
7
+ Foundation, either version 3 of the License, or (at your option) any later
8
+ version.
9
+
10
+ This program is distributed in the hope that it will be useful, but
11
+ WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
+ See the GNU General Public License for more details.
14
+
15
+ You should have received a copy of the GNU General Public License along with
16
+ this program. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.initSyncedFile = initSyncedFile;
20
+ exports.watchAndApplyChangesFromOtherDevices = watchAndApplyChangesFromOtherDevices;
21
+ const synced_1 = require("../processes/synced");
22
+ const utils_1 = require("./utils");
23
+ async function initSyncedFile(syncedFS, fName, initNewFile) {
24
+ const changeProc = new synced_1.SingleProc();
25
+ const file = await syncedFS.writableFile(fName);
26
+ if (file.isNew) {
27
+ await initNewFile(file);
28
+ }
29
+ await (0, utils_1.runRetryingButNotBlockingOnDisconnect)(async function ensureFileIsInFSTree() {
30
+ const { existsInSyncedParent, synced } = await file.v.sync.status(false);
31
+ if (!synced) {
32
+ await file.v.sync.upload();
33
+ }
34
+ if (!existsInSyncedParent) {
35
+ await syncedFS.v.sync.upload('.');
36
+ }
37
+ }, () => file.v.sync.whenConnected(), changeProc);
38
+ return { file, changeProc };
39
+ }
40
+ function watchAndApplyChangesFromOtherDevices(file, changeProc, onChangeFromOtherDevices, onConflictingChangeFromOtherDevices) {
41
+ function whenConnected() {
42
+ return file.v.sync.whenConnected();
43
+ }
44
+ const stopFileWatching = file.watch({
45
+ next: ev => {
46
+ if (ev.type === 'remote-change') {
47
+ (0, utils_1.runRetryingButNotBlockingOnDisconnect)(() => checkStatusAndSyncFile(true), whenConnected, changeProc);
48
+ }
49
+ else if ((ev.type === 'file-change') && (ev.src === 'sync')) {
50
+ onChangeFromOtherDevices(ev.newVersion, changeProc, file);
51
+ }
52
+ }
53
+ });
54
+ function triggerUpload() {
55
+ (0, utils_1.runRetryingButNotBlockingOnDisconnect)(() => file.v.sync.upload(), whenConnected, changeProc);
56
+ }
57
+ async function checkStatusAndSyncFile(skipServerCheck) {
58
+ const { state } = await file.v.sync.status(skipServerCheck);
59
+ if (state === 'behind') {
60
+ await file.v.sync.adoptRemote();
61
+ }
62
+ else if (state === 'conflicting') {
63
+ onConflictingChangeFromOtherDevices(changeProc, file);
64
+ }
65
+ else if (state === 'unsynced') {
66
+ triggerUpload();
67
+ }
68
+ }
69
+ // starting initial check with changeProc, without waiting here
70
+ (0, utils_1.runRetryingButNotBlockingOnDisconnect)(checkStatusAndSyncFile, whenConnected);
71
+ return { stopFileWatching, triggerUpload };
72
+ }
73
+ Object.freeze(exports);
@@ -0,0 +1,16 @@
1
+ import { SingleProc } from "../processes/synced";
2
+ /**
3
+ * Returned promise resolves when action runs first time, successfully or not.
4
+ * On disconnect action will be triggered again but outside of return promise.
5
+ * @param action
6
+ * @param whenConnected
7
+ * @param changeProc when given, is used to chain action invocation
8
+ */
9
+ export declare function runRetryingButNotBlockingOnDisconnect(action: () => Promise<any>, whenConnected: () => Promise<void>, changeProc?: SingleProc): Promise<void>;
10
+ /**
11
+ * Returned promise resolves when action ultimately runs or fails, after all possible disconnects.
12
+ * @param action
13
+ * @param whenConnected
14
+ * @param changeProc when given, is used to chain action invocation
15
+ */
16
+ export declare function runRetryingOnDisconnectTillDone<T>(action: () => Promise<T>, whenConnected: () => Promise<void>, changeProc?: SingleProc): Promise<T>;
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ /*
3
+ Copyright (C) 2026 3NSoft Inc.
4
+
5
+ This program is free software: you can redistribute it and/or modify it under
6
+ the terms of the GNU General Public License as published by the Free Software
7
+ Foundation, either version 3 of the License, or (at your option) any later
8
+ version.
9
+
10
+ This program is distributed in the hope that it will be useful, but
11
+ WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
+ See the GNU General Public License for more details.
14
+
15
+ You should have received a copy of the GNU General Public License along with
16
+ this program. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.runRetryingButNotBlockingOnDisconnect = runRetryingButNotBlockingOnDisconnect;
20
+ exports.runRetryingOnDisconnectTillDone = runRetryingOnDisconnectTillDone;
21
+ /**
22
+ * Returned promise resolves when action runs first time, successfully or not.
23
+ * On disconnect action will be triggered again but outside of return promise.
24
+ * @param action
25
+ * @param whenConnected
26
+ * @param changeProc when given, is used to chain action invocation
27
+ */
28
+ async function runRetryingButNotBlockingOnDisconnect(action, whenConnected, changeProc) {
29
+ if (changeProc) {
30
+ await changeProc.startOrChain(action).catch((exc) => {
31
+ if (exc.type === 'connect') {
32
+ whenConnected().then(() => runRetryingButNotBlockingOnDisconnect(() => changeProc.startOrChain(action), whenConnected, changeProc));
33
+ }
34
+ });
35
+ }
36
+ else {
37
+ await action().catch((exc) => {
38
+ if (exc.type === 'connect') {
39
+ whenConnected().then(() => runRetryingButNotBlockingOnDisconnect(action, whenConnected));
40
+ }
41
+ });
42
+ }
43
+ }
44
+ /**
45
+ * Returned promise resolves when action ultimately runs or fails, after all possible disconnects.
46
+ * @param action
47
+ * @param whenConnected
48
+ * @param changeProc when given, is used to chain action invocation
49
+ */
50
+ async function runRetryingOnDisconnectTillDone(action, whenConnected, changeProc) {
51
+ if (changeProc) {
52
+ return await changeProc.startOrChain(action).catch((exc) => {
53
+ if (exc.type === 'connect') {
54
+ return whenConnected().then(() => runRetryingOnDisconnectTillDone(() => changeProc.startOrChain(action), whenConnected, changeProc));
55
+ }
56
+ else {
57
+ throw exc;
58
+ }
59
+ });
60
+ }
61
+ else {
62
+ return await action().catch((exc) => {
63
+ if (exc.type === 'connect') {
64
+ return whenConnected().then(() => runRetryingOnDisconnectTillDone(action, whenConnected));
65
+ }
66
+ else {
67
+ throw exc;
68
+ }
69
+ });
70
+ }
71
+ }
72
+ Object.freeze(exports);
@@ -0,0 +1,3 @@
1
+ type FSItem = web3n.files.FSItem;
2
+ export declare function sysFilesOnDevice(): Promise<FSItem>;
3
+ export {};
@@ -1,31 +1,39 @@
1
1
  "use strict";
2
2
  /*
3
3
  Copyright (C) 2022 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
7
7
  Foundation, either version 3 of the License, or (at your option) any later
8
8
  version.
9
-
9
+
10
10
  This program is distributed in the hope that it will be useful, but
11
11
  WITHOUT ANY WARRANTY; without even the implied warranty of
12
12
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
13
  See the GNU General Public License for more details.
14
-
14
+
15
15
  You should have received a copy of the GNU General Public License along with
16
16
  this program. If not, see <http://www.gnu.org/licenses/>.
17
17
  */
18
18
  Object.defineProperty(exports, "__esModule", { value: true });
19
- exports.appendArray = appendArray;
20
- function appendArray(arr, elems) {
21
- if (elems !== undefined) {
22
- if (Array.isArray(elems)) {
23
- arr.push(...elems);
24
- }
25
- else {
26
- arr.push(elems);
27
- }
19
+ exports.sysFilesOnDevice = sysFilesOnDevice;
20
+ const fs_collection_1 = require("../lib-client/fs-utils/fs-collection");
21
+ const lib_index_1 = require("../lib-index");
22
+ async function sysFilesOnDevice() {
23
+ const c = (0, fs_collection_1.makeFSCollection)();
24
+ if (process.platform === 'win32') {
25
+ const sysDrive = process.env.SystemDrive;
26
+ await c.set(sysDrive, {
27
+ isFolder: true,
28
+ item: await lib_index_1.DeviceFS.makeWritable(sysDrive)
29
+ });
28
30
  }
29
- return arr;
31
+ else {
32
+ await c.set('', {
33
+ isFolder: true,
34
+ item: await lib_index_1.DeviceFS.makeWritable('/')
35
+ });
36
+ }
37
+ return { isCollection: true, item: c };
30
38
  }
31
39
  Object.freeze(exports);
@@ -58,9 +58,9 @@ describe('ASMail keyring', () => {
58
58
  // run different peers' keyrings from different folders
59
59
  const peer1 = `keyring tester 1 @rock.cafe`;
60
60
  const peer2 = `keyring tester 2 @rock.cafe`;
61
- const p1FS = await (0, fs_sync_utils_1.getOrMakeSyncedDirOnInit)(dev1FS, peer1);
61
+ const p1FS = await (0, fs_sync_utils_1.getOrMakeDirOnInit)(dev1FS, peer1);
62
62
  const p1LocalFS = await dev1LocalFS.writableSubRoot(`local fs for ${peer1}`);
63
- const p2FS = await (0, fs_sync_utils_1.getOrMakeSyncedDirOnInit)(dev1FS, peer2);
63
+ const p2FS = await (0, fs_sync_utils_1.getOrMakeDirOnInit)(dev1FS, peer2);
64
64
  const p2LocalFS = await dev1LocalFS.writableSubRoot(`local fs for ${peer2}`);
65
65
  const peerKeys1 = await (0, peer_keys_1.makePeersKeyring)(p1FS, p1LocalFS, random_node_1.bytes, logger);
66
66
  const peerKeys2 = await (0, peer_keys_1.makePeersKeyring)(p2FS, p2LocalFS, random_node_1.bytes, logger);
@@ -31,6 +31,7 @@ const dns_1 = require("dns");
31
31
  const napi_nacl_1 = require("napi-nacl");
32
32
  const request_from_node_1 = require("../../lib-common-on-node/request-from-node");
33
33
  const websocket_from_node_1 = require("../../lib-common-on-node/websocket-from-node");
34
+ const device_fs_places_1 = require("../../lib-common-on-node/device-fs-places");
34
35
  exports.testApp = {
35
36
  appDomain: 'test.3nweb.app',
36
37
  capsRequested: {
@@ -91,7 +92,7 @@ class CoreRunner {
91
92
  resolve(texts);
92
93
  }
93
94
  }))
94
- }), napi_nacl_1.makeNativeCryptor, random_node_1.bytes);
95
+ }), device_fs_places_1.sysFilesOnDevice, napi_nacl_1.makeNativeCryptor, random_node_1.bytes);
95
96
  }
96
97
  async close() {
97
98
  if (this.appCaps) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "core-3nweb-client-lib",
3
- "version": "0.49.7",
3
+ "version": "0.50.0",
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",
@@ -1 +0,0 @@
1
- export declare function appendArray<T>(arr: T[], elems: T[] | T | undefined): T[];