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.
- package/build/api-defs/files.d.ts +1 -1
- package/build/core/asmail/delivery/per-recipient-wip.js +4 -0
- package/build/core/asmail/inbox/index.js +5 -1
- package/build/core/asmail/inbox/msg-indexing/index.js +8 -9
- package/build/core/asmail/index.js +3 -3
- package/build/core/asmail/sending-params/index.d.ts +13 -14
- package/build/core/asmail/sending-params/index.js +15 -35
- package/build/core/asmail/sending-params/invitations-anon.d.ts +7 -31
- package/build/core/asmail/sending-params/invitations-anon.js +77 -127
- package/build/core/asmail/sending-params/own-params.d.ts +5 -25
- package/build/core/asmail/sending-params/own-params.js +144 -97
- package/build/core/asmail/sending-params/params-from-others.d.ts +6 -16
- package/build/core/asmail/sending-params/params-from-others.js +88 -58
- package/build/core/index.d.ts +2 -1
- package/build/core/index.js +4 -4
- package/build/core/keyring/index.js +1 -1
- package/build/core/keyring/introductory-keys/published-intro-key.js +15 -15
- package/build/core/keyring/peer-keys/index.js +6 -7
- package/build/core/storage/index.d.ts +2 -1
- package/build/core/storage/index.js +4 -3
- package/build/core/storage/system-folders/index.d.ts +1 -2
- package/build/core/storage/system-folders/index.js +18 -22
- package/build/lib-client/fs-utils/fs-sync-utils.d.ts +1 -1
- package/build/lib-client/fs-utils/fs-sync-utils.js +21 -15
- package/build/lib-client/xsp-fs/util/file-based-json.js +1 -1
- package/build/lib-common/dataset-sync/per-device-json-array-logs.js +42 -27
- package/build/lib-common/dataset-sync/single-file.d.ts +4 -2
- package/build/lib-common/dataset-sync/single-file.js +27 -31
- package/build/lib-common/dataset-sync/utils.d.ts +16 -0
- package/build/lib-common/dataset-sync/utils.js +72 -0
- package/build/lib-common-on-node/device-fs-places.d.ts +3 -0
- package/build/lib-common-on-node/device-fs-places.js +39 -0
- package/build/tests/computer.3nweb.core/keyrings.js +2 -2
- package/build/tests/libs-for-tests/core-runner.js +2 -1
- 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<
|
|
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
|
|
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
|
|
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
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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
|
-
|
|
71
|
-
|
|
72
|
-
|
|
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 {
|
|
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
|
|
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.
|
|
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
|
|
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
|
|
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
|
|
63
|
+
async function attemptToBringToSyncedState(syncedFS) {
|
|
62
64
|
const { existsInSyncedParent, state, remote } = await syncedFS.v.sync.status('');
|
|
63
|
-
|
|
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
|
-
|
|
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.
|
|
124
|
+
const content = (await logsFS.readTxtFile(logFile));
|
|
126
125
|
if (!content) {
|
|
127
126
|
return;
|
|
128
127
|
}
|
|
129
|
-
const appendedEvents = deserializeLogs(
|
|
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
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
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<
|
|
5
|
-
|
|
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
|
-
|
|
30
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
61
|
-
|
|
57
|
+
async function checkStatusAndSyncFile(skipServerCheck) {
|
|
58
|
+
const { state } = await file.v.sync.status(skipServerCheck);
|
|
62
59
|
if (state === 'behind') {
|
|
63
|
-
await
|
|
60
|
+
await file.v.sync.adoptRemote();
|
|
64
61
|
}
|
|
65
62
|
else if (state === 'conflicting') {
|
|
66
|
-
|
|
63
|
+
onConflictingChangeFromOtherDevices(changeProc, file);
|
|
67
64
|
}
|
|
68
65
|
else if (state === 'unsynced') {
|
|
69
66
|
triggerUpload();
|
|
70
67
|
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
|
|
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,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.
|
|
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.
|
|
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) {
|