core-3nweb-client-lib 0.49.8 → 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 (35) hide show
  1. package/build/api-defs/files.d.ts +1 -1
  2. package/build/core/asmail/delivery/per-recipient-wip.js +4 -0
  3. package/build/core/asmail/inbox/index.js +5 -1
  4. package/build/core/asmail/inbox/msg-indexing/index.js +8 -9
  5. package/build/core/asmail/index.js +3 -3
  6. package/build/core/asmail/sending-params/index.d.ts +13 -14
  7. package/build/core/asmail/sending-params/index.js +15 -35
  8. package/build/core/asmail/sending-params/invitations-anon.d.ts +7 -31
  9. package/build/core/asmail/sending-params/invitations-anon.js +77 -127
  10. package/build/core/asmail/sending-params/own-params.d.ts +5 -25
  11. package/build/core/asmail/sending-params/own-params.js +144 -97
  12. package/build/core/asmail/sending-params/params-from-others.d.ts +6 -16
  13. package/build/core/asmail/sending-params/params-from-others.js +88 -58
  14. package/build/core/index.d.ts +2 -1
  15. package/build/core/index.js +4 -4
  16. package/build/core/keyring/index.js +1 -1
  17. package/build/core/keyring/introductory-keys/published-intro-key.js +15 -15
  18. package/build/core/keyring/peer-keys/index.js +6 -7
  19. package/build/core/storage/index.d.ts +2 -1
  20. package/build/core/storage/index.js +4 -3
  21. package/build/core/storage/system-folders/index.d.ts +1 -2
  22. package/build/core/storage/system-folders/index.js +18 -22
  23. package/build/lib-client/fs-utils/fs-sync-utils.d.ts +1 -1
  24. package/build/lib-client/fs-utils/fs-sync-utils.js +21 -15
  25. package/build/lib-client/xsp-fs/util/file-based-json.js +1 -1
  26. package/build/lib-common/dataset-sync/per-device-json-array-logs.js +42 -27
  27. package/build/lib-common/dataset-sync/single-file.d.ts +4 -2
  28. package/build/lib-common/dataset-sync/single-file.js +27 -31
  29. package/build/lib-common/dataset-sync/utils.d.ts +16 -0
  30. package/build/lib-common/dataset-sync/utils.js +72 -0
  31. package/build/lib-common-on-node/device-fs-places.d.ts +3 -0
  32. package/build/lib-common-on-node/device-fs-places.js +39 -0
  33. package/build/tests/computer.3nweb.core/keyrings.js +2 -2
  34. package/build/tests/libs-for-tests/core-runner.js +2 -1
  35. package/package.json +1 -1
@@ -13,6 +13,5 @@ export declare const sysFolders: {
13
13
  * @param root
14
14
  */
15
15
  export declare function initSysFolders(root: WritableFS): Promise<void>;
16
- export declare function userFilesOnDevice(): Promise<WritableFS>;
17
- export declare function sysFilesOnDevice(): Promise<FSItem>;
16
+ export declare function userFilesOnDevice(): Promise<FSItem>;
18
17
  export {};
@@ -19,7 +19,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
19
19
  exports.sysFolders = void 0;
20
20
  exports.initSysFolders = initSysFolders;
21
21
  exports.userFilesOnDevice = userFilesOnDevice;
22
- exports.sysFilesOnDevice = sysFilesOnDevice;
23
22
  const fs_collection_1 = require("../../../lib-client/fs-utils/fs-collection");
24
23
  const lib_index_1 = require("../../../lib-index");
25
24
  exports.sysFolders = {
@@ -40,38 +39,35 @@ async function initSysFolders(root) {
40
39
  for (const sysFolder of Object.values(exports.sysFolders)) {
41
40
  await root.makeFolder(sysFolder);
42
41
  if ((_a = root.v) === null || _a === void 0 ? void 0 : _a.sync) {
43
- // XXX must add work with not-online condition
42
+ // XXX need not-online condition, but it runs only on first install, when network is required
44
43
  await root.v.sync.upload(sysFolder);
45
44
  }
46
45
  }
47
46
  if ((_b = root.v) === null || _b === void 0 ? void 0 : _b.sync) {
48
- // XXX must add work with not-online condition
47
+ // XXX need not-online condition, but it runs only on first install, when network is required
49
48
  await root.v.sync.upload('.');
50
49
  }
51
50
  }
52
51
  async function userFilesOnDevice() {
53
52
  if (process.platform === 'win32') {
54
- return lib_index_1.DeviceFS.makeWritable(process.env.USERPROFILE);
55
- }
56
- else {
57
- return lib_index_1.DeviceFS.makeWritable(process.env.HOME);
58
- }
59
- }
60
- async function sysFilesOnDevice() {
61
- const c = (0, fs_collection_1.makeFSCollection)();
62
- if (process.platform === 'win32') {
63
- const sysDrive = process.env.SystemDrive;
64
- await c.set(sysDrive, {
65
- isFolder: true,
66
- item: await lib_index_1.DeviceFS.makeWritable(sysDrive)
67
- });
53
+ if (process.env.USERPROFILE) {
54
+ return {
55
+ isFolder: true,
56
+ item: await lib_index_1.DeviceFS.makeWritable(process.env.USERPROFILE)
57
+ };
58
+ }
68
59
  }
69
60
  else {
70
- await c.set('', {
71
- isFolder: true,
72
- item: await lib_index_1.DeviceFS.makeWritable('/')
73
- });
61
+ if (process.env.HOME) {
62
+ return {
63
+ isFolder: true,
64
+ item: await lib_index_1.DeviceFS.makeWritable(process.env.HOME)
65
+ };
66
+ }
74
67
  }
75
- return { isCollection: true, item: c };
68
+ return {
69
+ isCollection: true,
70
+ item: (0, fs_collection_1.makeFSCollection)()
71
+ };
76
72
  }
77
73
  Object.freeze(exports);
@@ -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 {
@@ -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 {
@@ -408,10 +422,11 @@ function startDatasetSync(periodicCheckAndUploadOfData, millisBeforeNextRun, log
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(datasetCheckAndSyncAction, 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
@@ -1,9 +1,11 @@
1
1
  import { SingleProc } from "../processes/synced";
2
2
  type WritableFS = web3n.files.WritableFS;
3
3
  type WritableFile = web3n.files.WritableFile;
4
- export declare function initSyncedFile(syncedFS: WritableFS, fName: string, initNewFile: (newFile: WritableFile) => Promise<void>): Promise<WritableFile>;
5
- export declare function watchAndApplyChangesFromOtherDevices(file: WritableFile, onChangeFromOtherDevices: (changeProc: SingleProc, file: WritableFile) => Promise<void>, onConflictingChangeFromOtherDevices: (changeProc: SingleProc, file: WritableFile) => Promise<void>): {
4
+ export declare function initSyncedFile(syncedFS: WritableFS, fName: string, initNewFile: (newFile: WritableFile) => Promise<void>): Promise<{
5
+ file: WritableFile;
6
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>): {
7
9
  stopFileWatching: () => void;
8
10
  triggerUpload: () => void;
9
11
  };
@@ -19,59 +19,55 @@ Object.defineProperty(exports, "__esModule", { value: true });
19
19
  exports.initSyncedFile = initSyncedFile;
20
20
  exports.watchAndApplyChangesFromOtherDevices = watchAndApplyChangesFromOtherDevices;
21
21
  const synced_1 = require("../processes/synced");
22
+ const utils_1 = require("./utils");
22
23
  async function initSyncedFile(syncedFS, fName, initNewFile) {
24
+ const changeProc = new synced_1.SingleProc();
23
25
  const file = await syncedFS.writableFile(fName);
24
26
  if (file.isNew) {
25
27
  await initNewFile(file);
26
- await file.v.sync.upload();
27
- await syncedFS.v.sync.upload('.');
28
28
  }
29
- // XXX add initial sync no-connection handling
30
- return file;
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 };
31
39
  }
32
- function watchAndApplyChangesFromOtherDevices(file, onChangeFromOtherDevices, onConflictingChangeFromOtherDevices) {
33
- const changeProc = new synced_1.SingleProc();
40
+ function watchAndApplyChangesFromOtherDevices(file, changeProc, onChangeFromOtherDevices, onConflictingChangeFromOtherDevices) {
41
+ function whenConnected() {
42
+ return file.v.sync.whenConnected();
43
+ }
34
44
  const stopFileWatching = file.watch({
35
45
  next: ev => {
36
46
  if (ev.type === 'remote-change') {
37
- changeProc.startOrChain(async () => {
38
- await file.v.sync.adoptRemote({ remoteVersion: ev.newRemoteVersion })
39
- .catch((exc) => {
40
- if (exc.type === 'connect') {
41
- // XXX need to have watcher for connection to continue processing
42
- }
43
- });
44
- });
47
+ (0, utils_1.runRetryingButNotBlockingOnDisconnect)(() => checkStatusAndSyncFile(true), whenConnected, changeProc);
45
48
  }
46
49
  else if ((ev.type === 'file-change') && (ev.src === 'sync')) {
47
- onChangeFromOtherDevices(changeProc, file);
50
+ onChangeFromOtherDevices(ev.newVersion, changeProc, file);
48
51
  }
49
52
  }
50
53
  });
51
54
  function triggerUpload() {
52
- changeProc.startOrChain(async () => file.v.sync.upload())
53
- .catch((exc) => {
54
- if (exc.type === 'connect') {
55
- // XXX need to have watcher for connection to complete upload
56
- // Should this whole try-to-connect method be generic to reuse it?
57
- }
58
- });
55
+ (0, utils_1.runRetryingButNotBlockingOnDisconnect)(() => file.v.sync.upload(), whenConnected, changeProc);
59
56
  }
60
- file.v.sync.status()
61
- .then(async ({ state }) => {
57
+ async function checkStatusAndSyncFile(skipServerCheck) {
58
+ const { state } = await file.v.sync.status(skipServerCheck);
62
59
  if (state === 'behind') {
63
- await changeProc.startOrChain(() => file.v.sync.adoptRemote());
60
+ await file.v.sync.adoptRemote();
64
61
  }
65
62
  else if (state === 'conflicting') {
66
- await onConflictingChangeFromOtherDevices(changeProc, file);
63
+ onConflictingChangeFromOtherDevices(changeProc, file);
67
64
  }
68
65
  else if (state === 'unsynced') {
69
66
  triggerUpload();
70
67
  }
71
- })
72
- .catch(exc => {
73
- // XXX need to have watcher for connection to continue processing
74
- });
75
- return { changeProc, stopFileWatching, triggerUpload };
68
+ }
69
+ // starting initial check with changeProc, without waiting here
70
+ (0, utils_1.runRetryingButNotBlockingOnDisconnect)(checkStatusAndSyncFile, whenConnected);
71
+ return { stopFileWatching, triggerUpload };
76
72
  }
77
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 {};
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ /*
3
+ Copyright (C) 2022 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.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
+ });
30
+ }
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 };
38
+ }
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.8",
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",