core-3nweb-client-lib 0.43.6 → 0.43.8
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 +33 -0
- package/build/core/storage/synced/obj-status.d.ts +21 -0
- package/build/core/storage/synced/obj-status.js +45 -2
- package/build/core/storage/synced/upsyncer.js +1 -2
- package/build/core-ipc/file.d.ts +4 -0
- package/build/core-ipc/file.js +52 -8
- package/build/core-ipc/fs.js +22 -0
- package/build/lib-client/fs-utils/files.js +4 -0
- package/build/lib-client/xsp-fs/file-node.d.ts +3 -2
- package/build/lib-client/xsp-fs/file-node.js +30 -11
- package/build/lib-client/xsp-fs/file.d.ts +1 -0
- package/build/lib-client/xsp-fs/file.js +8 -12
- package/build/lib-client/xsp-fs/folder-node.d.ts +2 -0
- package/build/lib-client/xsp-fs/folder-node.js +21 -1
- package/build/lib-client/xsp-fs/fs.d.ts +1 -0
- package/build/lib-client/xsp-fs/fs.js +8 -25
- package/build/lib-client/xsp-fs/link-node.d.ts +3 -0
- package/build/lib-client/xsp-fs/link-node.js +20 -0
- package/build/lib-client/xsp-fs/node-in-fs.d.ts +2 -1
- package/build/lib-client/xsp-fs/node-in-fs.js +0 -3
- package/build/lib-client/xsp-fs/node-persistence.d.ts +1 -0
- package/build/lib-client/xsp-fs/node-persistence.js +4 -0
- package/build/lib-common/big-endian.js +2 -2
- package/build/protos/asmail.proto.js +345 -0
- package/build/protos/file.proto.js +345 -0
- package/build/protos/fs.proto.js +345 -0
- package/package.json +1 -1
- package/protos/file.proto +11 -0
- package/protos/fs.proto +5 -1
|
@@ -169,6 +169,7 @@ declare namespace web3n.files {
|
|
|
169
169
|
local?: LocalVersion;
|
|
170
170
|
remote?: SyncVersionsBranch;
|
|
171
171
|
existsInSyncedParent?: boolean;
|
|
172
|
+
uploading?: UploadingState;
|
|
172
173
|
}
|
|
173
174
|
|
|
174
175
|
interface LocalVersion {
|
|
@@ -184,6 +185,24 @@ declare namespace web3n.files {
|
|
|
184
185
|
|
|
185
186
|
type SyncState = 'synced' | 'behind' | 'unsynced' | 'conflicting';
|
|
186
187
|
|
|
188
|
+
interface UploadingState {
|
|
189
|
+
/**
|
|
190
|
+
* Local version that is uploaded to server.
|
|
191
|
+
* If it is an upload of object removal, version is -1.
|
|
192
|
+
*/
|
|
193
|
+
localVersion: number;
|
|
194
|
+
/**
|
|
195
|
+
* New remote version that is uploaded to server.
|
|
196
|
+
* If it is an upload of object removal, version is -1.
|
|
197
|
+
*/
|
|
198
|
+
remoteVersion: number;
|
|
199
|
+
/**
|
|
200
|
+
* Bytes left to upload.
|
|
201
|
+
*/
|
|
202
|
+
bytesLeftToUpload: number;
|
|
203
|
+
uploadStarted: boolean;
|
|
204
|
+
}
|
|
205
|
+
|
|
187
206
|
interface FileByteSource {
|
|
188
207
|
|
|
189
208
|
/**
|
|
@@ -445,6 +464,12 @@ declare namespace web3n.files {
|
|
|
445
464
|
|
|
446
465
|
interface ReadonlyFileVersionedAPI {
|
|
447
466
|
|
|
467
|
+
/**
|
|
468
|
+
* This returns a promise, resolvable to stats of the file.
|
|
469
|
+
* @param flags are optional flags to read archived or remote versions.
|
|
470
|
+
*/
|
|
471
|
+
stat(flags?: VersionedReadFlags): Promise<Stats>;
|
|
472
|
+
|
|
448
473
|
getXAttr(
|
|
449
474
|
xaName: string, flags?: VersionedReadFlags
|
|
450
475
|
): Promise<{ attr: any; version: number; }>;
|
|
@@ -1063,6 +1088,14 @@ declare namespace web3n.files {
|
|
|
1063
1088
|
|
|
1064
1089
|
interface ReadonlyFSVersionedAPI {
|
|
1065
1090
|
|
|
1091
|
+
/**
|
|
1092
|
+
* This returns a promise, resolvable to stats of an entity at a given
|
|
1093
|
+
* path.
|
|
1094
|
+
* @param path
|
|
1095
|
+
* @param flags are optional flags to read archived or remote versions.
|
|
1096
|
+
*/
|
|
1097
|
+
stat(path: string, flags?: VersionedReadFlags): Promise<Stats>;
|
|
1098
|
+
|
|
1066
1099
|
getXAttr(
|
|
1067
1100
|
path: string, xaName: string, flags?: VersionedReadFlags
|
|
1068
1101
|
): Promise<{ attr: any; version: number; }>;
|
|
@@ -48,16 +48,37 @@ export interface RemovalUpload {
|
|
|
48
48
|
export interface WholeVerOrderedUpload {
|
|
49
49
|
type: 'ordered-whole';
|
|
50
50
|
createObj?: boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Header bytes that need to be uploaded. Undefined when header has been uploaded.
|
|
53
|
+
*/
|
|
51
54
|
header?: number;
|
|
55
|
+
/**
|
|
56
|
+
* Segments bytes left to upload.
|
|
57
|
+
*/
|
|
52
58
|
segsLeft: number;
|
|
59
|
+
/**
|
|
60
|
+
* Offset in segments, to which point bytes where uploaded.
|
|
61
|
+
*/
|
|
53
62
|
segsOfs: number;
|
|
63
|
+
/**
|
|
64
|
+
* Upload transaction id.
|
|
65
|
+
*/
|
|
54
66
|
transactionId?: string;
|
|
55
67
|
}
|
|
56
68
|
export interface DiffVerOrderedUpload {
|
|
57
69
|
type: 'ordered-diff';
|
|
58
70
|
diff: DiffInfo;
|
|
71
|
+
/**
|
|
72
|
+
* Header bytes that need to be uploaded. Undefined when header has been uploaded.
|
|
73
|
+
*/
|
|
59
74
|
header?: number;
|
|
75
|
+
/**
|
|
76
|
+
* New chunks of segments that should be uploaded.
|
|
77
|
+
*/
|
|
60
78
|
newSegsLeft: FiniteChunk[];
|
|
79
|
+
/**
|
|
80
|
+
* Upload transaction id.
|
|
81
|
+
*/
|
|
61
82
|
transactionId?: string;
|
|
62
83
|
}
|
|
63
84
|
export interface BytesSection {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/*
|
|
3
|
-
Copyright (C) 2016 - 2020, 2022 3NSoft Inc.
|
|
3
|
+
Copyright (C) 2016 - 2020, 2022, 2025 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
|
|
@@ -494,7 +494,8 @@ class ObjStatus {
|
|
|
494
494
|
state: this.stateIndicator,
|
|
495
495
|
local: localVersionFromStatus(this.status.local),
|
|
496
496
|
remote,
|
|
497
|
-
synced
|
|
497
|
+
synced,
|
|
498
|
+
uploading: uploadInStatus(this.status.upload)
|
|
498
499
|
};
|
|
499
500
|
}
|
|
500
501
|
neverUploaded() {
|
|
@@ -674,4 +675,46 @@ function skipNotFoundExc(exc) {
|
|
|
674
675
|
throw exc;
|
|
675
676
|
}
|
|
676
677
|
}
|
|
678
|
+
function uploadInStatus(upload) {
|
|
679
|
+
if (!upload) {
|
|
680
|
+
return;
|
|
681
|
+
}
|
|
682
|
+
if (upload.type === 'new-version') {
|
|
683
|
+
const { needUpload } = upload;
|
|
684
|
+
if (!needUpload) {
|
|
685
|
+
return;
|
|
686
|
+
}
|
|
687
|
+
let bytesLeftToUpload = 0;
|
|
688
|
+
if (needUpload.type === 'ordered-whole') {
|
|
689
|
+
const { header, segsLeft } = needUpload;
|
|
690
|
+
if (header) {
|
|
691
|
+
bytesLeftToUpload += header;
|
|
692
|
+
}
|
|
693
|
+
bytesLeftToUpload += segsLeft;
|
|
694
|
+
}
|
|
695
|
+
else if (needUpload.type === 'ordered-diff') {
|
|
696
|
+
const { header, newSegsLeft } = needUpload;
|
|
697
|
+
if (header) {
|
|
698
|
+
bytesLeftToUpload += header;
|
|
699
|
+
}
|
|
700
|
+
for (const { len: chunkLen } of newSegsLeft) {
|
|
701
|
+
bytesLeftToUpload += chunkLen;
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
return {
|
|
705
|
+
localVersion: upload.localVersion,
|
|
706
|
+
remoteVersion: upload.uploadVersion,
|
|
707
|
+
bytesLeftToUpload,
|
|
708
|
+
uploadStarted: !!needUpload.transactionId
|
|
709
|
+
};
|
|
710
|
+
}
|
|
711
|
+
else {
|
|
712
|
+
return {
|
|
713
|
+
localVersion: -1,
|
|
714
|
+
remoteVersion: -1,
|
|
715
|
+
bytesLeftToUpload: 0,
|
|
716
|
+
uploadStarted: false
|
|
717
|
+
};
|
|
718
|
+
}
|
|
719
|
+
}
|
|
677
720
|
Object.freeze(exports);
|
|
@@ -181,8 +181,7 @@ class UploadTask {
|
|
|
181
181
|
}
|
|
182
182
|
}
|
|
183
183
|
async headerToUpload() {
|
|
184
|
-
return (this.uploadHeader ?
|
|
185
|
-
this.uploadHeader : await this.src.readHeader());
|
|
184
|
+
return (this.uploadHeader ? this.uploadHeader : await this.src.readHeader());
|
|
186
185
|
}
|
|
187
186
|
async startOrderedDiffUpload(upload) {
|
|
188
187
|
const diff = buffer_utils_1.utf8.pack(JSON.stringify(upload.diff));
|
package/build/core-ipc/file.d.ts
CHANGED
|
@@ -47,6 +47,10 @@ export interface VersionedReadFlagsMsg {
|
|
|
47
47
|
}
|
|
48
48
|
export declare function versionedReadFlagsFromMsg(msg: VersionedReadFlagsMsg | undefined): VersionedReadFlags | undefined;
|
|
49
49
|
export declare function versionedReadFlagsToMsg(flags: VersionedReadFlags | undefined): VersionedReadFlagsMsg | undefined;
|
|
50
|
+
export declare namespace vStat {
|
|
51
|
+
function wrapService(fn: ReadonlyFileVersionedAPI['stat']): ExposedFn;
|
|
52
|
+
function makeCaller(caller: Caller, objPath: string[]): ReadonlyFileVersionedAPI['stat'];
|
|
53
|
+
}
|
|
50
54
|
export declare namespace vGetXAttr {
|
|
51
55
|
interface Reply {
|
|
52
56
|
version: number;
|
package/build/core-ipc/file.js
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
17
|
*/
|
|
18
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
-
exports.vListVersions = exports.vGetByteSink = exports.updateXAttrs = exports.vGetByteSource = exports.vReadJSON = exports.vReadTxt = exports.vReadBytes = exports.vListXAttrs = exports.vGetXAttr = exports.readBytes = exports.fileMsgType = void 0;
|
|
19
|
+
exports.vListVersions = exports.vGetByteSink = exports.updateXAttrs = exports.vGetByteSource = exports.vReadJSON = exports.vReadTxt = exports.vReadBytes = exports.vListXAttrs = exports.vGetXAttr = exports.vStat = exports.readBytes = exports.fileMsgType = void 0;
|
|
20
20
|
exports.makeFileCaller = makeFileCaller;
|
|
21
21
|
exports.exposeFileService = exposeFileService;
|
|
22
22
|
exports.packStats = packStats;
|
|
@@ -75,6 +75,7 @@ function makeFileCaller(caller, fileMsg) {
|
|
|
75
75
|
const vPath = (0, protobuf_msg_1.methodPathFor)(objPath, 'v');
|
|
76
76
|
file.v = {
|
|
77
77
|
getByteSource: vGetByteSource.makeCaller(caller, vPath),
|
|
78
|
+
stat: vStat.makeCaller(caller, vPath),
|
|
78
79
|
getXAttr: vGetXAttr.makeCaller(caller, vPath),
|
|
79
80
|
listXAttrs: vListXAttrs.makeCaller(caller, vPath),
|
|
80
81
|
readBytes: vReadBytes.makeCaller(caller, vPath),
|
|
@@ -129,6 +130,7 @@ function exposeFileService(file, expServices) {
|
|
|
129
130
|
if (file.v) {
|
|
130
131
|
implExp.v = {
|
|
131
132
|
getByteSource: vGetByteSource.wrapService(file.v.getByteSource, expServices),
|
|
133
|
+
stat: vStat.wrapService(file.v.stat),
|
|
132
134
|
getXAttr: vGetXAttr.wrapService(file.v.getXAttr),
|
|
133
135
|
listXAttrs: vListXAttrs.wrapService(file.v.listXAttrs),
|
|
134
136
|
readBytes: vReadBytes.wrapService(file.v.readBytes),
|
|
@@ -171,7 +173,10 @@ function exposeFileService(file, expServices) {
|
|
|
171
173
|
exports.fileMsgType = protobuf_type_1.ProtoType.for(file_proto_1.file.File);
|
|
172
174
|
const statsMsgType = protobuf_type_1.ProtoType.for(file_proto_1.file.StatsMsg);
|
|
173
175
|
function packStats(s) {
|
|
174
|
-
|
|
176
|
+
return statsMsgType.pack(statsToMsg(s));
|
|
177
|
+
}
|
|
178
|
+
function statsToMsg(s) {
|
|
179
|
+
return {
|
|
175
180
|
writable: s.writable,
|
|
176
181
|
isFile: (0, protobuf_msg_1.toOptVal)(s.isFile),
|
|
177
182
|
isFolder: (0, protobuf_msg_1.toOptVal)(s.isFolder),
|
|
@@ -181,10 +186,11 @@ function packStats(s) {
|
|
|
181
186
|
size: (0, protobuf_msg_1.toOptVal)(s.size),
|
|
182
187
|
version: (0, protobuf_msg_1.toOptVal)(s.version),
|
|
183
188
|
};
|
|
184
|
-
return statsMsgType.pack(msg);
|
|
185
189
|
}
|
|
186
190
|
function unpackStats(buf) {
|
|
187
|
-
|
|
191
|
+
return msgToStats(statsMsgType.unpack(buf));
|
|
192
|
+
}
|
|
193
|
+
function msgToStats(m) {
|
|
188
194
|
return {
|
|
189
195
|
writable: m.writable,
|
|
190
196
|
isFile: (0, protobuf_msg_1.valOfOpt)(m.isFile),
|
|
@@ -205,7 +211,8 @@ function syncStatusToMsg(s) {
|
|
|
205
211
|
local: syncBranchToMsg(s.local),
|
|
206
212
|
synced: syncBranchToMsg(s.synced),
|
|
207
213
|
remote: syncBranchToMsg(s.remote),
|
|
208
|
-
existsInSyncedParent: (0, protobuf_msg_1.toOptVal)(s.existsInSyncedParent)
|
|
214
|
+
existsInSyncedParent: (0, protobuf_msg_1.toOptVal)(s.existsInSyncedParent),
|
|
215
|
+
uploading: uploadingToMsg(s.uploading)
|
|
209
216
|
};
|
|
210
217
|
}
|
|
211
218
|
function msgToSyncStatus(m) {
|
|
@@ -217,7 +224,8 @@ function msgToSyncStatus(m) {
|
|
|
217
224
|
local: msgToSyncBranch(m.local),
|
|
218
225
|
synced: msgToSyncBranch(m.synced),
|
|
219
226
|
remote: msgToSyncBranch(m.remote),
|
|
220
|
-
existsInSyncedParent: (0, protobuf_msg_1.valOfOpt)(m.existsInSyncedParent)
|
|
227
|
+
existsInSyncedParent: (0, protobuf_msg_1.valOfOpt)(m.existsInSyncedParent),
|
|
228
|
+
uploading: msgToUploading(m.uploading)
|
|
221
229
|
};
|
|
222
230
|
}
|
|
223
231
|
function syncBranchToMsg(b) {
|
|
@@ -236,11 +244,28 @@ function msgToSyncBranch(m) {
|
|
|
236
244
|
}
|
|
237
245
|
return {
|
|
238
246
|
latest: (0, protobuf_msg_1.valOfOptInt)(m.latest),
|
|
239
|
-
archived: ((m.archived.length > 0) ?
|
|
240
|
-
m.archived.map(protobuf_msg_1.fixInt) : undefined),
|
|
247
|
+
archived: ((m.archived.length > 0) ? m.archived.map(protobuf_msg_1.fixInt) : undefined),
|
|
241
248
|
isArchived: (0, protobuf_msg_1.valOfOpt)(m.isArchived)
|
|
242
249
|
};
|
|
243
250
|
}
|
|
251
|
+
function uploadingToMsg(u) {
|
|
252
|
+
if (!u) {
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
const { localVersion, remoteVersion, uploadStarted, bytesLeftToUpload } = u;
|
|
256
|
+
return { localVersion, remoteVersion, uploadStarted, bytesLeftToUpload };
|
|
257
|
+
}
|
|
258
|
+
function msgToUploading(u) {
|
|
259
|
+
if (!u) {
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
return {
|
|
263
|
+
localVersion: (0, protobuf_msg_1.fixInt)(u.localVersion),
|
|
264
|
+
remoteVersion: (0, protobuf_msg_1.fixInt)(u.remoteVersion),
|
|
265
|
+
bytesLeftToUpload: (0, protobuf_msg_1.fixInt)(u.bytesLeftToUpload),
|
|
266
|
+
uploadStarted: u.uploadStarted
|
|
267
|
+
};
|
|
268
|
+
}
|
|
244
269
|
const syncStatusMsgType = protobuf_type_1.ProtoType.for(file_proto_1.file.SyncStatusMsg);
|
|
245
270
|
function packSyncStatus(s) {
|
|
246
271
|
return syncStatusMsgType.pack(syncStatusToMsg(s));
|
|
@@ -556,6 +581,25 @@ function versionedReadFlagsToMsg(flags) {
|
|
|
556
581
|
remoteVersion: (0, protobuf_msg_1.toOptVal)(flags.remoteVersion)
|
|
557
582
|
};
|
|
558
583
|
}
|
|
584
|
+
var vStat;
|
|
585
|
+
(function (vStat) {
|
|
586
|
+
function wrapService(fn) {
|
|
587
|
+
return buf => {
|
|
588
|
+
const promise = fn(unpackVersionedReadFlagsRequest(buf))
|
|
589
|
+
.then(packStats);
|
|
590
|
+
return { promise };
|
|
591
|
+
};
|
|
592
|
+
}
|
|
593
|
+
vStat.wrapService = wrapService;
|
|
594
|
+
function makeCaller(caller, objPath) {
|
|
595
|
+
const path = (0, protobuf_msg_1.methodPathFor)(objPath, 'stat');
|
|
596
|
+
return flags => caller
|
|
597
|
+
.startPromiseCall(path, packVersionedReadFlagsRequest(flags))
|
|
598
|
+
.then(unpackStats);
|
|
599
|
+
}
|
|
600
|
+
vStat.makeCaller = makeCaller;
|
|
601
|
+
})(vStat || (exports.vStat = vStat = {}));
|
|
602
|
+
Object.freeze(vStat);
|
|
559
603
|
var vGetXAttr;
|
|
560
604
|
(function (vGetXAttr) {
|
|
561
605
|
const requestType = protobuf_type_1.ProtoType.for(file_proto_1.file.VersionedGetXAttrRequestBody);
|
package/build/core-ipc/fs.js
CHANGED
|
@@ -83,6 +83,7 @@ function makeFSCaller(caller, fsMsg) {
|
|
|
83
83
|
const vPath = (0, protobuf_msg_1.methodPathFor)(objPath, 'v');
|
|
84
84
|
fs.v = {
|
|
85
85
|
getByteSource: vGetByteSource.makeCaller(caller, vPath),
|
|
86
|
+
stat: vStat.makeCaller(caller, vPath),
|
|
86
87
|
getXAttr: vGetXAttr.makeCaller(caller, vPath),
|
|
87
88
|
listXAttrs: vListXAttrs.makeCaller(caller, vPath),
|
|
88
89
|
listFolder: vListFolder.makeCaller(caller, vPath),
|
|
@@ -161,6 +162,7 @@ function exposeFSService(fs, expServices) {
|
|
|
161
162
|
if (fs.v) {
|
|
162
163
|
implExp.v = {
|
|
163
164
|
getByteSource: vGetByteSource.wrapService(fs.v.getByteSource, expServices),
|
|
165
|
+
stat: vStat.wrapService(fs.v.stat),
|
|
164
166
|
getXAttr: vGetXAttr.wrapService(fs.v.getXAttr),
|
|
165
167
|
listXAttrs: vListXAttrs.wrapService(fs.v.listXAttrs),
|
|
166
168
|
listFolder: vListFolder.wrapService(fs.v.listFolder),
|
|
@@ -1181,6 +1183,26 @@ function unpackRequestWithPathAndFlags(buf) {
|
|
|
1181
1183
|
flags: file.versionedReadFlagsFromMsg(flags)
|
|
1182
1184
|
};
|
|
1183
1185
|
}
|
|
1186
|
+
var vStat;
|
|
1187
|
+
(function (vStat) {
|
|
1188
|
+
function wrapService(fn) {
|
|
1189
|
+
return buf => {
|
|
1190
|
+
const { path, flags } = unpackRequestWithPathAndFlags(buf);
|
|
1191
|
+
const promise = fn(path, flags)
|
|
1192
|
+
.then(file.packStats);
|
|
1193
|
+
return { promise };
|
|
1194
|
+
};
|
|
1195
|
+
}
|
|
1196
|
+
vStat.wrapService = wrapService;
|
|
1197
|
+
function makeCaller(caller, objPath) {
|
|
1198
|
+
const ipcPath = (0, protobuf_msg_1.methodPathFor)(objPath, 'stat');
|
|
1199
|
+
return (path, flags) => caller
|
|
1200
|
+
.startPromiseCall(ipcPath, packRequestWithPathAndFlags(path, flags))
|
|
1201
|
+
.then(file.unpackStats);
|
|
1202
|
+
}
|
|
1203
|
+
vStat.makeCaller = makeCaller;
|
|
1204
|
+
})(vStat || (vStat = {}));
|
|
1205
|
+
Object.freeze(vStat);
|
|
1184
1206
|
var vGetXAttr;
|
|
1185
1207
|
(function (vGetXAttr) {
|
|
1186
1208
|
const requestType = protobuf_type_1.ProtoType.for(fs_proto_1.fs.VersionedGetXAttrRequestBody);
|
|
@@ -62,6 +62,7 @@ function wrapWritableFileVersionedAPI(vImpl) {
|
|
|
62
62
|
return;
|
|
63
63
|
}
|
|
64
64
|
const w = {
|
|
65
|
+
stat: vImpl.stat.bind(vImpl),
|
|
65
66
|
getXAttr: vImpl.getXAttr.bind(vImpl),
|
|
66
67
|
listXAttrs: vImpl.listXAttrs.bind(vImpl),
|
|
67
68
|
updateXAttrs: vImpl.updateXAttrs.bind(vImpl),
|
|
@@ -120,6 +121,7 @@ function wrapReadonlyFileVersionedAPI(vImpl) {
|
|
|
120
121
|
return;
|
|
121
122
|
}
|
|
122
123
|
const w = {
|
|
124
|
+
stat: vImpl.stat.bind(vImpl),
|
|
123
125
|
getXAttr: vImpl.getXAttr.bind(vImpl),
|
|
124
126
|
listXAttrs: vImpl.listXAttrs.bind(vImpl),
|
|
125
127
|
getByteSource: vImpl.getByteSource.bind(vImpl),
|
|
@@ -206,6 +208,7 @@ function wrapWritableFSVersionedAPI(vImpl) {
|
|
|
206
208
|
return;
|
|
207
209
|
}
|
|
208
210
|
const w = {
|
|
211
|
+
stat: vImpl.stat.bind(vImpl),
|
|
209
212
|
getXAttr: vImpl.getXAttr.bind(vImpl),
|
|
210
213
|
listXAttrs: vImpl.listXAttrs.bind(vImpl),
|
|
211
214
|
updateXAttrs: vImpl.updateXAttrs.bind(vImpl),
|
|
@@ -272,6 +275,7 @@ function wrapReadonlyFSVersionedAPI(vImpl) {
|
|
|
272
275
|
return;
|
|
273
276
|
}
|
|
274
277
|
const w = {
|
|
278
|
+
stat: vImpl.stat.bind(vImpl),
|
|
275
279
|
getXAttr: vImpl.getXAttr.bind(vImpl),
|
|
276
280
|
listXAttrs: vImpl.listXAttrs.bind(vImpl),
|
|
277
281
|
getByteSource: vImpl.getByteSource.bind(vImpl),
|
|
@@ -12,6 +12,7 @@ type FileByteSource = web3n.files.FileByteSource;
|
|
|
12
12
|
type FileByteSink = web3n.files.FileByteSink;
|
|
13
13
|
type XAttrsChanges = web3n.files.XAttrsChanges;
|
|
14
14
|
type VersionedReadFlags = web3n.files.VersionedReadFlags;
|
|
15
|
+
type Stats = web3n.files.Stats;
|
|
15
16
|
interface FileAttrs {
|
|
16
17
|
attrs: CommonAttrs;
|
|
17
18
|
size: number;
|
|
@@ -19,7 +20,7 @@ interface FileAttrs {
|
|
|
19
20
|
}
|
|
20
21
|
declare class FilePersistance extends NodePersistance {
|
|
21
22
|
constructor(zNonce: Uint8Array, key: Uint8Array, cryptor: AsyncSBoxCryptor);
|
|
22
|
-
|
|
23
|
+
getFileAttrs(objSrc: ObjSource): Promise<FileAttrs>;
|
|
23
24
|
getFileSource(objSrc: ObjSource): Promise<FileByteSource>;
|
|
24
25
|
readBytes(objSrc: ObjSource, start: number | undefined, end: number | undefined): Promise<Uint8Array | undefined>;
|
|
25
26
|
saveBytes(bytes: Uint8Array | Uint8Array[], version: number, attrs: CommonAttrs, xattrs: XAttrs | undefined): Promise<Subscribe>;
|
|
@@ -42,7 +43,7 @@ export declare class FileNode extends NodeInFS<FilePersistance> {
|
|
|
42
43
|
private static initWithAttrs;
|
|
43
44
|
protected setCurrentStateFrom(src: ObjSource): Promise<void>;
|
|
44
45
|
private setUpdatedState;
|
|
45
|
-
|
|
46
|
+
getStats(flags?: VersionedReadFlags): Promise<Stats>;
|
|
46
47
|
readSrc(flags: VersionedReadFlags | undefined): Promise<{
|
|
47
48
|
src: FileByteSource;
|
|
48
49
|
version: number;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/*
|
|
3
|
-
Copyright (C) 2015 - 2020, 2022 3NSoft Inc.
|
|
3
|
+
Copyright (C) 2015 - 2020, 2022, 2025 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
|
|
@@ -29,19 +29,16 @@ const assert_1 = require("../../lib-common/assert");
|
|
|
29
29
|
const attrs_1 = require("./attrs");
|
|
30
30
|
const file_1 = require("../../lib-common/exceptions/file");
|
|
31
31
|
const node_persistence_1 = require("./node-persistence");
|
|
32
|
-
async function fileAttrsFrom(payload) {
|
|
33
|
-
const attrs = payload.getAttrs();
|
|
34
|
-
const xattrs = await payload.getXAttrs();
|
|
35
|
-
return { attrs: attrs_1.CommonAttrs.fromAttrs(attrs), size: attrs.size, xattrs };
|
|
36
|
-
}
|
|
37
32
|
class FilePersistance extends node_persistence_1.NodePersistance {
|
|
38
33
|
constructor(zNonce, key, cryptor) {
|
|
39
34
|
super(zNonce, key, cryptor);
|
|
40
35
|
Object.seal(this);
|
|
41
36
|
}
|
|
42
|
-
async
|
|
37
|
+
async getFileAttrs(objSrc) {
|
|
43
38
|
const payload = await super.readonlyPayload(objSrc);
|
|
44
|
-
|
|
39
|
+
const attrs = payload.getAttrs();
|
|
40
|
+
const xattrs = await payload.getXAttrs();
|
|
41
|
+
return { attrs: attrs_1.CommonAttrs.fromAttrs(attrs), size: attrs.size, xattrs };
|
|
45
42
|
}
|
|
46
43
|
async getFileSource(objSrc) {
|
|
47
44
|
const payload = await this.readonlyPayload(objSrc);
|
|
@@ -122,15 +119,37 @@ class FileNode extends node_in_fs_1.NodeInFS {
|
|
|
122
119
|
return file;
|
|
123
120
|
}
|
|
124
121
|
async setCurrentStateFrom(src) {
|
|
125
|
-
const fileAttrs = await this.crypto.
|
|
122
|
+
const fileAttrs = await this.crypto.getFileAttrs(src);
|
|
126
123
|
this.setUpdatedState(src.version, fileAttrs);
|
|
127
124
|
}
|
|
128
125
|
setUpdatedState(version, fileAttrs) {
|
|
129
126
|
this.fileSize = fileAttrs.size;
|
|
130
127
|
super.setUpdatedParams(version, fileAttrs.attrs, fileAttrs.xattrs);
|
|
131
128
|
}
|
|
132
|
-
|
|
133
|
-
|
|
129
|
+
async getStats(flags) {
|
|
130
|
+
let attrs;
|
|
131
|
+
let version;
|
|
132
|
+
let size;
|
|
133
|
+
if ((0, node_in_fs_1.shouldReadCurrentVersion)(flags)) {
|
|
134
|
+
attrs = this.attrs;
|
|
135
|
+
version = this.version;
|
|
136
|
+
size = this.fileSize;
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
const src = await this.getObjSrcOfVersion(flags);
|
|
140
|
+
const fileAttrs = await this.crypto.getFileAttrs(src);
|
|
141
|
+
attrs = fileAttrs.attrs;
|
|
142
|
+
version = src.version;
|
|
143
|
+
size = fileAttrs.size;
|
|
144
|
+
}
|
|
145
|
+
return {
|
|
146
|
+
ctime: new Date(attrs.ctime),
|
|
147
|
+
mtime: new Date(attrs.mtime),
|
|
148
|
+
version,
|
|
149
|
+
writable: false,
|
|
150
|
+
isFile: true,
|
|
151
|
+
size
|
|
152
|
+
};
|
|
134
153
|
}
|
|
135
154
|
async readSrc(flags) {
|
|
136
155
|
const objSrc = await this.getObjSrcOfVersion(flags);
|
|
@@ -54,6 +54,7 @@ declare class V implements WritableFileVersionedAPI, N {
|
|
|
54
54
|
constructor(name: string, node: FileNode | undefined, makeOrGetNode: (() => Promise<FileNode>) | undefined, writable: boolean, isInSyncedStorage: boolean);
|
|
55
55
|
getNode(): Promise<FileNode>;
|
|
56
56
|
ensureIsWritable(): void;
|
|
57
|
+
stat(flags?: VersionedReadFlags): Promise<Stats>;
|
|
57
58
|
updateXAttrs(changes: XAttrsChanges): Promise<number>;
|
|
58
59
|
getXAttr(xaName: string, flags?: VersionedReadFlags): Promise<{
|
|
59
60
|
attr: any;
|
|
@@ -54,18 +54,8 @@ class FileObject {
|
|
|
54
54
|
linkParams.readonly = !this.writable;
|
|
55
55
|
return linkParams;
|
|
56
56
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
const attrs = node.getAttrs();
|
|
60
|
-
const stat = {
|
|
61
|
-
writable: this.writable,
|
|
62
|
-
size: node.size,
|
|
63
|
-
version: node.version,
|
|
64
|
-
isFile: true,
|
|
65
|
-
ctime: new Date(attrs.ctime),
|
|
66
|
-
mtime: new Date(attrs.mtime),
|
|
67
|
-
};
|
|
68
|
-
return stat;
|
|
57
|
+
stat() {
|
|
58
|
+
return this.v.stat();
|
|
69
59
|
}
|
|
70
60
|
async updateXAttrs(changes) {
|
|
71
61
|
await this.v.updateXAttrs(changes);
|
|
@@ -143,6 +133,12 @@ class V {
|
|
|
143
133
|
throw new Error(`File is not writable`);
|
|
144
134
|
}
|
|
145
135
|
}
|
|
136
|
+
async stat(flags) {
|
|
137
|
+
const node = await this.getNode();
|
|
138
|
+
const stats = await node.getStats(flags);
|
|
139
|
+
stats.writable = this.writable;
|
|
140
|
+
return stats;
|
|
141
|
+
}
|
|
146
142
|
async updateXAttrs(changes) {
|
|
147
143
|
this.ensureIsWritable();
|
|
148
144
|
const node = await this.getNode();
|
|
@@ -13,6 +13,7 @@ type OptionsToAdopteRemote = web3n.files.OptionsToAdopteRemote;
|
|
|
13
13
|
type OptionsToAdoptRemoteItem = web3n.files.OptionsToAdoptRemoteItem;
|
|
14
14
|
type OptionsToUploadLocal = web3n.files.OptionsToUploadLocal;
|
|
15
15
|
type VersionedReadFlags = web3n.files.VersionedReadFlags;
|
|
16
|
+
type Stats = web3n.files.Stats;
|
|
16
17
|
export interface NodeInfo {
|
|
17
18
|
/**
|
|
18
19
|
* This is a usual file name.
|
|
@@ -74,6 +75,7 @@ export declare class FolderNode extends NodeInFS<FolderPersistance> {
|
|
|
74
75
|
private static readNodeFromObjBytes;
|
|
75
76
|
static rootFromLinkParams(storage: Storage, params: FolderLinkParams): Promise<FolderNode>;
|
|
76
77
|
static rootFromJSON(storage: Storage, name: string | undefined, folderJson: FolderInJSON): FolderNode;
|
|
78
|
+
getStats(flags?: VersionedReadFlags): Promise<Stats>;
|
|
77
79
|
protected setCurrentStateFrom(src: ObjSource): Promise<void>;
|
|
78
80
|
adoptRemote(opts: OptionsToAdopteRemote | undefined): Promise<void>;
|
|
79
81
|
private callRemoveObjOn;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/*
|
|
3
|
-
Copyright (C) 2015 - 2020, 2022 3NSoft Inc.
|
|
3
|
+
Copyright (C) 2015 - 2020, 2022, 2025 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
|
|
@@ -162,6 +162,26 @@ class FolderNode extends node_in_fs_1.NodeInFS {
|
|
|
162
162
|
rf.setUpdatedParams(0, attrs, xattrs);
|
|
163
163
|
return rf;
|
|
164
164
|
}
|
|
165
|
+
async getStats(flags) {
|
|
166
|
+
let attrs;
|
|
167
|
+
let version;
|
|
168
|
+
if ((0, node_in_fs_1.shouldReadCurrentVersion)(flags)) {
|
|
169
|
+
attrs = this.attrs;
|
|
170
|
+
version = this.version;
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
const src = await this.getObjSrcOfVersion(flags);
|
|
174
|
+
attrs = await this.crypto.getAttrs(src);
|
|
175
|
+
version = src.version;
|
|
176
|
+
}
|
|
177
|
+
return {
|
|
178
|
+
ctime: new Date(attrs.ctime),
|
|
179
|
+
mtime: new Date(attrs.mtime),
|
|
180
|
+
version,
|
|
181
|
+
writable: false,
|
|
182
|
+
isFolder: true,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
165
185
|
async setCurrentStateFrom(src) {
|
|
166
186
|
const { folderInfo, attrs, xattrs } = await this.crypto.read(src);
|
|
167
187
|
this.currentState = folderInfo;
|
|
@@ -121,6 +121,7 @@ declare class V implements WritableFSVersionedAPI, N {
|
|
|
121
121
|
getOrCreateFile(path: string, flags: FileFlags): Promise<FileNode>;
|
|
122
122
|
get(path: string): Promise<NodeInFS<any>>;
|
|
123
123
|
ensureIsWritable(): void;
|
|
124
|
+
stat(path: string, flags?: VersionedReadFlags): Promise<Stats>;
|
|
124
125
|
updateXAttrs(path: string, changes: XAttrsChanges): Promise<number>;
|
|
125
126
|
getXAttr(path: string, xaName: string, flags?: VersionedReadFlags): Promise<{
|
|
126
127
|
attr: any;
|
|
@@ -204,31 +204,8 @@ class XspFS {
|
|
|
204
204
|
throw exc;
|
|
205
205
|
}
|
|
206
206
|
}
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
const attrs = node.getAttrs();
|
|
210
|
-
const stats = {
|
|
211
|
-
ctime: new Date(attrs.ctime),
|
|
212
|
-
mtime: new Date(attrs.mtime),
|
|
213
|
-
version: node.version,
|
|
214
|
-
writable: this.writable,
|
|
215
|
-
};
|
|
216
|
-
if (node.type === 'file') {
|
|
217
|
-
stats.size = node.size;
|
|
218
|
-
stats.isFile = true;
|
|
219
|
-
return stats;
|
|
220
|
-
}
|
|
221
|
-
else if (node.type === 'folder') {
|
|
222
|
-
stats.isFolder = true;
|
|
223
|
-
return stats;
|
|
224
|
-
}
|
|
225
|
-
else if (node.type === 'link') {
|
|
226
|
-
stats.isLink = true;
|
|
227
|
-
return stats;
|
|
228
|
-
}
|
|
229
|
-
else {
|
|
230
|
-
throw new Error(`Unknown type of fs node`);
|
|
231
|
-
}
|
|
207
|
+
stat(path) {
|
|
208
|
+
return this.v.stat(path);
|
|
232
209
|
}
|
|
233
210
|
async updateXAttrs(path, changes) {
|
|
234
211
|
await this.v.updateXAttrs(path, changes);
|
|
@@ -551,6 +528,12 @@ class V {
|
|
|
551
528
|
throw new Error(`FS is not writable`);
|
|
552
529
|
}
|
|
553
530
|
}
|
|
531
|
+
async stat(path, flags) {
|
|
532
|
+
const node = await this.get(path);
|
|
533
|
+
const stats = await node.getStats(flags);
|
|
534
|
+
stats.writable = this.writable;
|
|
535
|
+
return stats;
|
|
536
|
+
}
|
|
554
537
|
async updateXAttrs(path, changes) {
|
|
555
538
|
this.ensureIsWritable();
|
|
556
539
|
const node = await this.get(path);
|
|
@@ -8,6 +8,8 @@ import { Storage, AsyncSBoxCryptor } from './common';
|
|
|
8
8
|
import { ObjSource, Subscribe } from 'xsp-files';
|
|
9
9
|
import { CommonAttrs, XAttrs } from './attrs';
|
|
10
10
|
import { NodePersistance } from './node-persistence';
|
|
11
|
+
type VersionedReadFlags = web3n.files.VersionedReadFlags;
|
|
12
|
+
type Stats = web3n.files.Stats;
|
|
11
13
|
declare class LinkPersistance extends NodePersistance {
|
|
12
14
|
constructor(zNonce: Uint8Array, key: Uint8Array, cryptor: AsyncSBoxCryptor);
|
|
13
15
|
read(src: ObjSource): Promise<{
|
|
@@ -25,6 +27,7 @@ export declare class LinkNode extends NodeInFS<LinkPersistance> {
|
|
|
25
27
|
static makeForNew(storage: Storage, parentId: string, name: string, key: Uint8Array): Promise<LinkNode>;
|
|
26
28
|
static makeForExisting(storage: Storage, parentId: string, name: string, objId: string, key: Uint8Array): Promise<LinkNode>;
|
|
27
29
|
protected setCurrentStateFrom(src: ObjSource): Promise<void>;
|
|
30
|
+
getStats(flags?: VersionedReadFlags): Promise<Stats>;
|
|
28
31
|
private setUpdatedState;
|
|
29
32
|
save(params: LinkParameters<any>, changes?: XAttrsChanges): Promise<void>;
|
|
30
33
|
private getLinkParams;
|