core-3nweb-client-lib 0.43.19 → 0.44.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 +236 -163
- package/build/core-ipc/file.d.ts +47 -0
- package/build/core-ipc/file.js +121 -2
- package/build/core-ipc/fs.js +55 -62
- package/build/lib-client/fs-utils/files.js +5 -1
- package/build/lib-client/xsp-fs/exceptions.js +1 -1
- package/build/lib-client/xsp-fs/file-node.d.ts +3 -0
- package/build/lib-client/xsp-fs/file-node.js +55 -3
- package/build/lib-client/xsp-fs/file.d.ts +3 -0
- package/build/lib-client/xsp-fs/file.js +5 -1
- package/build/lib-client/xsp-fs/folder-node.d.ts +5 -4
- package/build/lib-client/xsp-fs/folder-node.js +257 -367
- package/build/lib-client/xsp-fs/fs.d.ts +6 -2
- package/build/lib-client/xsp-fs/fs.js +33 -2
- package/build/lib-client/xsp-fs/link-node.js +1 -1
- package/build/lib-client/xsp-fs/node-in-fs.d.ts +21 -0
- package/build/lib-client/xsp-fs/node-in-fs.js +172 -3
- package/build/lib-common/exceptions/file.d.ts +1 -1
- package/build/lib-common/exceptions/file.js +3 -2
- package/build/protos/asmail.proto.js +3350 -872
- package/build/protos/file.proto.js +1974 -0
- package/build/protos/fs.proto.js +3235 -757
- package/package.json +1 -1
- package/protos/file.proto +44 -0
- package/protos/fs.proto +42 -25
|
@@ -28,9 +28,11 @@ type SyncStatus = web3n.files.SyncStatus;
|
|
|
28
28
|
type WritableFSVersionedAPI = web3n.files.WritableFSVersionedAPI;
|
|
29
29
|
type OptionsToAdopteRemote = web3n.files.OptionsToAdopteRemote;
|
|
30
30
|
type OptionsToAdoptRemoteItem = web3n.files.OptionsToAdoptRemoteItem;
|
|
31
|
-
type
|
|
31
|
+
type OptionsToDiffFileVersions = web3n.files.OptionsToDiffFileVersions;
|
|
32
32
|
type OptionsToUploadLocal = web3n.files.OptionsToUploadLocal;
|
|
33
33
|
type FolderDiff = web3n.files.FolderDiff;
|
|
34
|
+
type FileDiff = web3n.files.FileDiff;
|
|
35
|
+
type OptionsToMergeFolderVersions = web3n.files.OptionsToMergeFolderVersions;
|
|
34
36
|
export declare class XspFS implements WritableFS {
|
|
35
37
|
readonly writable: boolean;
|
|
36
38
|
name: string;
|
|
@@ -178,11 +180,13 @@ declare class S implements WritableFSSyncAPI {
|
|
|
178
180
|
adoptRemote(path: string, opts?: OptionsToAdopteRemote): Promise<void>;
|
|
179
181
|
private getFolderNode;
|
|
180
182
|
diffCurrentAndRemoteFolderVersions(path: string, remoteVersion?: number): Promise<FolderDiff | undefined>;
|
|
183
|
+
private getFileNode;
|
|
184
|
+
diffCurrentAndRemoteFileVersions(path: string, opts?: OptionsToDiffFileVersions): Promise<FileDiff | undefined>;
|
|
181
185
|
adoptRemoteFolderItem(path: string, itemName: string, opts?: OptionsToAdoptRemoteItem): Promise<number>;
|
|
182
186
|
statRemoteItem(path: string, remoteItemName: string, remoteVersion?: number): Promise<Stats>;
|
|
183
187
|
listRemoteFolderItem(path: string, remoteItemName: string, remoteVersion?: number): Promise<ListingEntry[]>;
|
|
184
188
|
getRemoteFileItem(path: string, remoteItemName: string, remoteVersion?: number): Promise<ReadonlyFile>;
|
|
185
189
|
getRemoteFolderItem(path: string, remoteItemName: string, remoteVersion?: number): Promise<ReadonlyFS>;
|
|
186
|
-
|
|
190
|
+
mergeFolderCurrentAndRemoteVersions(path: string, opts?: OptionsToMergeFolderVersions): Promise<number | undefined>;
|
|
187
191
|
}
|
|
188
192
|
export {};
|
|
@@ -799,6 +799,22 @@ class S {
|
|
|
799
799
|
throw (0, common_1.setPathInExc)(exc, path);
|
|
800
800
|
}
|
|
801
801
|
}
|
|
802
|
+
async getFileNode(path) {
|
|
803
|
+
const node = await this.n.get(path);
|
|
804
|
+
if (node.type !== 'file') {
|
|
805
|
+
throw (0, file_1.makeFileException)('notFile', path);
|
|
806
|
+
}
|
|
807
|
+
return node;
|
|
808
|
+
}
|
|
809
|
+
async diffCurrentAndRemoteFileVersions(path, opts) {
|
|
810
|
+
const node = await this.getFileNode(path);
|
|
811
|
+
try {
|
|
812
|
+
return await node.diffCurrentAndRemote(opts === null || opts === void 0 ? void 0 : opts.remoteVersion, !!(opts === null || opts === void 0 ? void 0 : opts.compareContentIfSameMTime));
|
|
813
|
+
}
|
|
814
|
+
catch (exc) {
|
|
815
|
+
throw (0, common_1.setPathInExc)(exc, path);
|
|
816
|
+
}
|
|
817
|
+
}
|
|
802
818
|
async adoptRemoteFolderItem(path, itemName, opts) {
|
|
803
819
|
const node = await this.getFolderNode(path);
|
|
804
820
|
try {
|
|
@@ -843,9 +859,24 @@ class S {
|
|
|
843
859
|
throw (0, file_1.makeFileException)('notDirectory', `${path}/${remoteItemName}`);
|
|
844
860
|
}
|
|
845
861
|
}
|
|
846
|
-
async adoptAllRemoteItems(
|
|
862
|
+
// async adoptAllRemoteItems(
|
|
863
|
+
// path: string, opts?: OptionsToAdoptAllRemoteItems
|
|
864
|
+
// ): Promise<number|undefined> {
|
|
865
|
+
// const folderNode = await this.getFolderNode(path);
|
|
866
|
+
// return await folderNode.adoptItemsFromRemoteVersion(opts);
|
|
867
|
+
// }
|
|
868
|
+
async mergeFolderCurrentAndRemoteVersions(path, opts) {
|
|
847
869
|
const folderNode = await this.getFolderNode(path);
|
|
848
|
-
|
|
870
|
+
const newLocalVersion = await folderNode.mergeCurrentAndRemoteVersions(opts);
|
|
871
|
+
if (newLocalVersion && (newLocalVersion < 0)) {
|
|
872
|
+
const { folderPath } = split(path);
|
|
873
|
+
if (folderPath.length > 0) {
|
|
874
|
+
const parent = await this.n.get(folderPath.join('/'));
|
|
875
|
+
// XXX removing folder in parent -- what happens with children?
|
|
876
|
+
await parent.removeChild(folderNode);
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
return newLocalVersion;
|
|
849
880
|
}
|
|
850
881
|
}
|
|
851
882
|
Object.freeze(S.prototype);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/*
|
|
3
|
-
Copyright (C) 2016 - 2018, 2020, 2022, 2025 3NSoft Inc.
|
|
3
|
+
Copyright (C) 2016 - 2018, 2020, 2022, 2025 - 2026 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
|
|
@@ -11,6 +11,8 @@ type OptionsToAdopteRemote = web3n.files.OptionsToAdopteRemote;
|
|
|
11
11
|
type OptionsToUploadLocal = web3n.files.OptionsToUploadLocal;
|
|
12
12
|
type VersionedReadFlags = web3n.files.VersionedReadFlags;
|
|
13
13
|
type Stats = web3n.files.Stats;
|
|
14
|
+
type CommonDiff = web3n.files.CommonDiff;
|
|
15
|
+
type SyncVersionsBranch = web3n.files.SyncVersionsBranch;
|
|
14
16
|
export declare abstract class NodeInFS<P extends NodePersistance> implements Node {
|
|
15
17
|
protected readonly storage: Storage;
|
|
16
18
|
readonly type: NodeType;
|
|
@@ -102,6 +104,25 @@ export declare abstract class NodeInFS<P extends NodePersistance> implements Nod
|
|
|
102
104
|
uploadTaskId: number;
|
|
103
105
|
}>;
|
|
104
106
|
private makeHeaderForUploadIfVersionChanges;
|
|
107
|
+
private diffWithArchivedRemote;
|
|
108
|
+
protected commonDiffWithRemote(isCurrentLocal: boolean, remoteVersion: number, remote: {
|
|
109
|
+
attrs: CommonAttrs;
|
|
110
|
+
xattrs?: XAttrs;
|
|
111
|
+
}, syncedVersion: number, synced: {
|
|
112
|
+
attrs: CommonAttrs;
|
|
113
|
+
xattrs?: XAttrs;
|
|
114
|
+
}): CommonDiff;
|
|
115
|
+
protected getRemoteVersionToDiff(remoteVersion: number | undefined): Promise<{
|
|
116
|
+
rm: false;
|
|
117
|
+
isCurrentLocal: boolean;
|
|
118
|
+
remoteVersion: number;
|
|
119
|
+
syncedVersion?: number;
|
|
120
|
+
} | {
|
|
121
|
+
rm: true;
|
|
122
|
+
rmDiff: CommonDiff;
|
|
123
|
+
} | undefined>;
|
|
105
124
|
}
|
|
106
125
|
export declare function shouldReadCurrentVersion(flags: VersionedReadFlags | undefined): boolean;
|
|
126
|
+
export declare function areBytesEqual(b1: Uint8Array, b2: Uint8Array): boolean;
|
|
127
|
+
export declare function versionFromRemoteBranch(remote: SyncVersionsBranch, remoteVersion: number | undefined): number | undefined;
|
|
107
128
|
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/*
|
|
3
|
-
Copyright (C) 2015 - 2020, 2022, 2025 3NSoft Inc.
|
|
3
|
+
Copyright (C) 2015 - 2020, 2022, 2025 - 2026 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
|
|
@@ -18,6 +18,8 @@
|
|
|
18
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
19
|
exports.NodeInFS = void 0;
|
|
20
20
|
exports.shouldReadCurrentVersion = shouldReadCurrentVersion;
|
|
21
|
+
exports.areBytesEqual = areBytesEqual;
|
|
22
|
+
exports.versionFromRemoteBranch = versionFromRemoteBranch;
|
|
21
23
|
/**
|
|
22
24
|
* Everything in this module is assumed to be inside of a file system
|
|
23
25
|
* reliance set.
|
|
@@ -32,6 +34,7 @@ const operators_1 = require("rxjs/operators");
|
|
|
32
34
|
const attrs_1 = require("./attrs");
|
|
33
35
|
const assert_1 = require("../../lib-common/assert");
|
|
34
36
|
const runtime_1 = require("../../lib-common/exceptions/runtime");
|
|
37
|
+
const json_utils_1 = require("../../lib-common/json-utils");
|
|
35
38
|
class NodeInFS {
|
|
36
39
|
get version() {
|
|
37
40
|
return this.currentVersion;
|
|
@@ -346,8 +349,7 @@ class NodeInFS {
|
|
|
346
349
|
if (this.parentId) {
|
|
347
350
|
const parent = storage.nodes.get(this.parentId);
|
|
348
351
|
if (parent) {
|
|
349
|
-
status.existsInSyncedParent =
|
|
350
|
-
await parent.childExistsInSyncedVersion(this.objId);
|
|
352
|
+
status.existsInSyncedParent = await parent.childExistsInSyncedVersion(this.objId);
|
|
351
353
|
}
|
|
352
354
|
}
|
|
353
355
|
return status;
|
|
@@ -523,6 +525,46 @@ class NodeInFS {
|
|
|
523
525
|
const uploadHeader = await this.crypto.reencryptHeader(localHeader, uploadVersion);
|
|
524
526
|
return { localHeader, localVersion, uploadHeader, uploadVersion };
|
|
525
527
|
}
|
|
528
|
+
diffWithArchivedRemote(isCurrentLocal) {
|
|
529
|
+
return {
|
|
530
|
+
currentVersion: this.version,
|
|
531
|
+
isCurrentLocal,
|
|
532
|
+
isRemoteRemoved: true,
|
|
533
|
+
};
|
|
534
|
+
}
|
|
535
|
+
commonDiffWithRemote(isCurrentLocal, remoteVersion, remote, syncedVersion, synced) {
|
|
536
|
+
const { ctime, mtime } = diffAttrs(this.attrs, remote.attrs, synced.attrs);
|
|
537
|
+
return {
|
|
538
|
+
currentVersion: this.version,
|
|
539
|
+
isCurrentLocal,
|
|
540
|
+
isRemoteRemoved: false,
|
|
541
|
+
remoteVersion,
|
|
542
|
+
syncedVersion,
|
|
543
|
+
ctime,
|
|
544
|
+
mtime,
|
|
545
|
+
xattrs: diffXAttrs(this.xattrs, remote.xattrs, synced.xattrs)
|
|
546
|
+
};
|
|
547
|
+
}
|
|
548
|
+
async getRemoteVersionToDiff(remoteVersion) {
|
|
549
|
+
const { state, remote, synced } = await this.syncStatus();
|
|
550
|
+
let isCurrentLocal;
|
|
551
|
+
if (state === 'behind') {
|
|
552
|
+
isCurrentLocal = false;
|
|
553
|
+
}
|
|
554
|
+
else if (state === 'conflicting') {
|
|
555
|
+
isCurrentLocal = true;
|
|
556
|
+
}
|
|
557
|
+
else {
|
|
558
|
+
return;
|
|
559
|
+
}
|
|
560
|
+
remoteVersion = versionFromRemoteBranch(remote, remoteVersion);
|
|
561
|
+
if (remoteVersion) {
|
|
562
|
+
return { rm: false, isCurrentLocal, remoteVersion, syncedVersion: synced === null || synced === void 0 ? void 0 : synced.latest };
|
|
563
|
+
}
|
|
564
|
+
else {
|
|
565
|
+
return { rm: true, rmDiff: this.diffWithArchivedRemote(isCurrentLocal) };
|
|
566
|
+
}
|
|
567
|
+
}
|
|
526
568
|
}
|
|
527
569
|
exports.NodeInFS = NodeInFS;
|
|
528
570
|
Object.freeze(NodeInFS.prototype);
|
|
@@ -558,4 +600,131 @@ function shouldReadCurrentVersion(flags) {
|
|
|
558
600
|
}
|
|
559
601
|
return true;
|
|
560
602
|
}
|
|
603
|
+
function diffAttrs(current, remote, synced) {
|
|
604
|
+
return {
|
|
605
|
+
ctime: {
|
|
606
|
+
current: new Date(current.ctime),
|
|
607
|
+
remote: new Date(remote.ctime),
|
|
608
|
+
synced: new Date(synced.ctime)
|
|
609
|
+
},
|
|
610
|
+
mtime: {
|
|
611
|
+
current: new Date(current.mtime),
|
|
612
|
+
remote: new Date(remote.mtime),
|
|
613
|
+
synced: new Date(synced.mtime)
|
|
614
|
+
}
|
|
615
|
+
};
|
|
616
|
+
}
|
|
617
|
+
function diffXAttrs(current, remote, synced) {
|
|
618
|
+
const diff = {};
|
|
619
|
+
const checkedNames = new Set();
|
|
620
|
+
if (current) {
|
|
621
|
+
for (const name of current.list()) {
|
|
622
|
+
const localValue = current.get(name);
|
|
623
|
+
const syncedValue = synced === null || synced === void 0 ? void 0 : synced.get(name);
|
|
624
|
+
const remoteValue = remote === null || remote === void 0 ? void 0 : remote.get(name);
|
|
625
|
+
if (remoteValue === undefined) {
|
|
626
|
+
if (syncedValue === undefined) {
|
|
627
|
+
diff[name] = { addedIn: 'l' };
|
|
628
|
+
}
|
|
629
|
+
else if (areXAttrValuesEqual(localValue, syncedValue)) {
|
|
630
|
+
diff[name] = { removedIn: 'r' };
|
|
631
|
+
}
|
|
632
|
+
else {
|
|
633
|
+
diff[name] = { removedIn: 'r', changedIn: 'l' };
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
else if (areXAttrValuesEqual(localValue, remoteValue)) {
|
|
637
|
+
// no differences between local and remote
|
|
638
|
+
}
|
|
639
|
+
else {
|
|
640
|
+
if (syncedValue === undefined) {
|
|
641
|
+
diff[name] = { addedIn: 'l&r', changedIn: 'l&r' };
|
|
642
|
+
}
|
|
643
|
+
else if (areXAttrValuesEqual(localValue, syncedValue)) {
|
|
644
|
+
diff[name] = { changedIn: 'r' };
|
|
645
|
+
}
|
|
646
|
+
else {
|
|
647
|
+
diff[name] = { changedIn: 'l&r' };
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
checkedNames.add(name);
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
if (remote) {
|
|
654
|
+
for (const name of remote.list()) {
|
|
655
|
+
if (checkedNames.has(name)) {
|
|
656
|
+
continue;
|
|
657
|
+
}
|
|
658
|
+
const remoteValue = remote.get(name);
|
|
659
|
+
const syncedValue = synced === null || synced === void 0 ? void 0 : synced.get(name);
|
|
660
|
+
if (syncedValue === undefined) {
|
|
661
|
+
diff[name] = { addedIn: 'r' };
|
|
662
|
+
}
|
|
663
|
+
else if (areXAttrValuesEqual(remoteValue, syncedValue)) {
|
|
664
|
+
diff[name] = { removedIn: 'l' };
|
|
665
|
+
}
|
|
666
|
+
else {
|
|
667
|
+
diff[name] = { removedIn: 'l', changedIn: 'r' };
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
return ((Object.keys(diff).length > 0) ? diff : undefined);
|
|
672
|
+
}
|
|
673
|
+
function areXAttrValuesEqual(v1, v2) {
|
|
674
|
+
if (Buffer.isBuffer(v1) || ArrayBuffer.isView(v1)) {
|
|
675
|
+
if (Buffer.isBuffer(v2) || ArrayBuffer.isView(v2)) {
|
|
676
|
+
return areBytesEqual(v1, v2);
|
|
677
|
+
}
|
|
678
|
+
{
|
|
679
|
+
return false;
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
else if (typeof v1 === 'string') {
|
|
683
|
+
if (typeof v2 === 'string') {
|
|
684
|
+
return (v1 === v2);
|
|
685
|
+
}
|
|
686
|
+
else {
|
|
687
|
+
return false;
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
else {
|
|
691
|
+
if (Buffer.isBuffer(v2) || ArrayBuffer.isView(v2)
|
|
692
|
+
|| (typeof v2 === 'string')) {
|
|
693
|
+
return false;
|
|
694
|
+
}
|
|
695
|
+
else {
|
|
696
|
+
return (0, json_utils_1.deepEqual)(v1, v2);
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
function areBytesEqual(b1, b2) {
|
|
701
|
+
if (b1.length !== b2.length) {
|
|
702
|
+
return false;
|
|
703
|
+
}
|
|
704
|
+
for (let i = 0; i < b1.length; i += 1) {
|
|
705
|
+
if (b1[i] !== b2[i]) {
|
|
706
|
+
return false;
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
return true;
|
|
710
|
+
}
|
|
711
|
+
function versionFromRemoteBranch(remote, remoteVersion) {
|
|
712
|
+
var _a;
|
|
713
|
+
if (remote.isArchived) {
|
|
714
|
+
return;
|
|
715
|
+
}
|
|
716
|
+
if (remoteVersion) {
|
|
717
|
+
if ((remoteVersion !== remote.latest)
|
|
718
|
+
&& !((_a = remote.archived) === null || _a === void 0 ? void 0 : _a.includes(remoteVersion))) {
|
|
719
|
+
throw (0, exceptions_1.makeFSSyncException)(this.name, {
|
|
720
|
+
versionMismatch: true,
|
|
721
|
+
message: `Unknown remote version ${remoteVersion}`
|
|
722
|
+
});
|
|
723
|
+
}
|
|
724
|
+
return remoteVersion;
|
|
725
|
+
}
|
|
726
|
+
else {
|
|
727
|
+
return remote.latest;
|
|
728
|
+
}
|
|
729
|
+
}
|
|
561
730
|
Object.freeze(exports);
|
|
@@ -6,4 +6,4 @@ export declare function makeFileException(flag: keyof FileExceptionFlag, path: s
|
|
|
6
6
|
export declare function maskPathInExc(pathPrefixMaskLen: number, exc: any): FileException;
|
|
7
7
|
export declare function ensureCorrectFS(fs: web3n.files.FS, type: web3n.files.FSType, writable: boolean): void;
|
|
8
8
|
export declare function makeNoAttrsExc(path: string): FileException;
|
|
9
|
-
export declare function makeVersionMismatchExc(path: string): FileException;
|
|
9
|
+
export declare function makeVersionMismatchExc(path: string, message?: string): FileException;
|
|
@@ -98,13 +98,14 @@ function makeNoAttrsExc(path) {
|
|
|
98
98
|
attrsNotEnabledInFS: true
|
|
99
99
|
};
|
|
100
100
|
}
|
|
101
|
-
function makeVersionMismatchExc(path) {
|
|
101
|
+
function makeVersionMismatchExc(path, message) {
|
|
102
102
|
return {
|
|
103
103
|
runtimeException: true,
|
|
104
104
|
type: 'file',
|
|
105
105
|
code: undefined,
|
|
106
106
|
path,
|
|
107
|
-
versionMismatch: true
|
|
107
|
+
versionMismatch: true,
|
|
108
|
+
message
|
|
108
109
|
};
|
|
109
110
|
}
|
|
110
111
|
Object.freeze(exports);
|