core-3nweb-client-lib 0.20.9 → 0.23.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 (67) hide show
  1. package/build/api-defs/common-caps.d.ts +6 -10
  2. package/build/api-defs/files.d.ts +8 -7
  3. package/build/core/asmail/inbox/attachments/fs.d.ts +2 -2
  4. package/build/core/asmail/inbox/attachments/fs.js +3 -2
  5. package/build/core/asmail/msg/common.d.ts +2 -2
  6. package/build/core/asmail/msg/common.js +3 -2
  7. package/build/core/asmail/msg/opener.d.ts +2 -2
  8. package/build/core/asmail/msg/opener.js +3 -2
  9. package/build/core/asmail/msg/packer.d.ts +2 -2
  10. package/build/core/asmail/msg/packer.js +7 -6
  11. package/build/core/index.d.ts +2 -2
  12. package/build/core/index.js +24 -28
  13. package/build/core/storage/index.js +2 -2
  14. package/build/core/storage/local/obj-files.js +8 -5
  15. package/build/core/storage/local/obj-status.js +4 -3
  16. package/build/core/storage/synced/obj-status.js +4 -3
  17. package/build/ipc-via-protobuf/bytes.js +1 -1
  18. package/build/ipc-via-protobuf/file.d.ts +4 -0
  19. package/build/ipc-via-protobuf/file.js +17 -15
  20. package/build/ipc-via-protobuf/fs.js +1 -1
  21. package/build/lib-client/3nstorage/xsp-fs/attrs.d.ts +28 -0
  22. package/build/lib-client/3nstorage/xsp-fs/attrs.js +337 -0
  23. package/build/lib-client/3nstorage/xsp-fs/common.d.ts +1 -1
  24. package/build/lib-client/3nstorage/xsp-fs/common.js +3 -2
  25. package/build/lib-client/3nstorage/xsp-fs/file-node.d.ts +31 -18
  26. package/build/lib-client/3nstorage/xsp-fs/file-node.js +130 -118
  27. package/build/lib-client/3nstorage/xsp-fs/file.d.ts +0 -1
  28. package/build/lib-client/3nstorage/xsp-fs/file.js +14 -49
  29. package/build/lib-client/3nstorage/xsp-fs/folder-node-serialization.d.ts +1 -1
  30. package/build/lib-client/3nstorage/xsp-fs/folder-node-serialization.js +95 -91
  31. package/build/lib-client/3nstorage/xsp-fs/folder-node.d.ts +19 -24
  32. package/build/lib-client/3nstorage/xsp-fs/folder-node.js +133 -190
  33. package/build/lib-client/3nstorage/xsp-fs/fs.d.ts +3 -4
  34. package/build/lib-client/3nstorage/xsp-fs/fs.js +18 -21
  35. package/build/lib-client/3nstorage/xsp-fs/link-node.d.ts +13 -8
  36. package/build/lib-client/3nstorage/xsp-fs/link-node.js +46 -38
  37. package/build/lib-client/3nstorage/xsp-fs/node-in-fs.d.ts +17 -35
  38. package/build/lib-client/3nstorage/xsp-fs/node-in-fs.js +34 -127
  39. package/build/lib-client/3nstorage/xsp-fs/node-persistence.d.ts +57 -0
  40. package/build/lib-client/3nstorage/xsp-fs/node-persistence.js +182 -0
  41. package/build/lib-client/3nstorage/xsp-fs/xsp-payload-v1.d.ts +3 -0
  42. package/build/lib-client/3nstorage/xsp-fs/xsp-payload-v1.js +87 -0
  43. package/build/lib-client/3nstorage/xsp-fs/xsp-payload-v2.d.ts +6 -0
  44. package/build/lib-client/3nstorage/xsp-fs/xsp-payload-v2.js +1022 -0
  45. package/build/lib-client/cryptor/cryptor-wasm.js +1 -1
  46. package/build/lib-client/cryptor/cryptor.wasm +0 -0
  47. package/build/lib-client/local-files/device-fs.js +7 -3
  48. package/build/lib-client/objs-on-disk/file-writing-proc.js +3 -2
  49. package/build/lib-client/objs-on-disk/obj-on-disk.js +8 -7
  50. package/build/lib-common/big-endian.d.ts +0 -24
  51. package/build/lib-common/big-endian.js +16 -78
  52. package/build/lib-common/exceptions/file.js +6 -2
  53. package/build/lib-common/obj-streaming/sink-utils.d.ts +0 -4
  54. package/build/lib-common/obj-streaming/sink-utils.js +4 -70
  55. package/build/lib-common/objs-on-disk/file-layout.js +2 -1
  56. package/build/lib-common/objs-on-disk/obj-file.js +2 -2
  57. package/build/lib-common/objs-on-disk/utils.js +2 -1
  58. package/build/lib-common/objs-on-disk/v1-obj-file-format.js +2 -1
  59. package/package.json +2 -2
  60. package/build/lib-client/files/file-attrs.d.ts +0 -76
  61. package/build/lib-client/files/file-attrs.js +0 -549
  62. package/build/lib-client/files/file-layout.d.ts +0 -56
  63. package/build/lib-client/files/file-layout.js +0 -456
  64. package/build/lib-client/files/file-sink.d.ts +0 -33
  65. package/build/lib-client/files/file-sink.js +0 -173
  66. package/build/lib-client/files/file-source.d.ts +0 -19
  67. package/build/lib-client/files/file-source.js +0 -115
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /*
3
- Copyright (C) 2015 - 2020 3NSoft Inc.
3
+ Copyright (C) 2015 - 2020, 2022 3NSoft Inc.
4
4
 
5
5
  This program is free software: you can redistribute it and/or modify it under
6
6
  the terms of the GNU General Public License as published by the Free Software
@@ -13,7 +13,8 @@
13
13
  See the GNU General Public License for more details.
14
14
 
15
15
  You should have received a copy of the GNU General Public License along with
16
- this program. If not, see <http://www.gnu.org/licenses/>. */
16
+ this program. If not, see <http://www.gnu.org/licenses/>.
17
+ */
17
18
  Object.defineProperty(exports, "__esModule", { value: true });
18
19
  exports.FileNode = void 0;
19
20
  /**
@@ -25,96 +26,78 @@ const buffer_utils_1 = require("../../../lib-common/buffer-utils");
25
26
  const processes_1 = require("../../../lib-common/processes");
26
27
  const xsp_files_1 = require("xsp-files");
27
28
  const assert_1 = require("../../../lib-common/assert");
28
- const file_source_1 = require("../../files/file-source");
29
- const file_sink_1 = require("../../files/file-sink");
30
- const file_attrs_1 = require("../../files/file-attrs");
31
- const file_layout_1 = require("../../files/file-layout");
29
+ const attrs_1 = require("./attrs");
32
30
  const file_1 = require("../../../lib-common/exceptions/file");
33
- class FileCrypto extends node_in_fs_1.NodeCrypto {
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
+ class FilePersistance extends node_persistence_1.NodePersistance {
34
38
  constructor(zNonce, key, cryptor) {
35
39
  super(zNonce, key, cryptor);
36
40
  Object.seal(this);
37
41
  }
38
- async getAttrsAndByteSrc(src) {
39
- const { byteSrc, attrsBytes } = await super.getAttrsAndByteSrc(src);
40
- if (attrsBytes) {
41
- return {
42
- byteSrc,
43
- attrs: file_attrs_1.AttrsHolder.fromBytesReadonly(attrsBytes),
44
- attrsByteSize: attrsBytes.length
45
- };
46
- }
47
- else {
48
- return { byteSrc };
49
- }
50
- }
51
- async decryptedBytesSource(src) {
52
- const { byteSrc, attrs } = await this.getAttrsAndByteSrc(src);
53
- const fileSrc = await file_source_1.FileBytes.from(byteSrc, attrs);
54
- return { attrs, fileSrc };
42
+ async getAttrs(objSrc) {
43
+ const payload = await super.readonlyPayload(objSrc);
44
+ return await fileAttrsFrom(payload);
55
45
  }
56
- async saveBytes(bytes, version, attrs) {
57
- attrs.setContinuousFileSize(Array.isArray(bytes) ?
58
- buffer_utils_1.byteLengthIn(bytes) : bytes.length);
59
- return super.saveBytes(bytes, version, attrs);
46
+ async getFileSource(objSrc, getAttrs = false) {
47
+ const payload = await this.readonlyPayload(objSrc);
48
+ const src = payload.makeFileByteSource();
49
+ return (getAttrs ?
50
+ { src, fileAttrs: await fileAttrsFrom(payload) } :
51
+ { src });
60
52
  }
61
- async encryptingByteSink(version, attrs, base) {
62
- attrs.mtime = Date.now();
63
- let writer;
64
- let baseAttrsSize;
65
- let layout;
66
- let initLayoutOfs;
67
- if (base) {
68
- writer = await this.segWriterWithBase(version, base);
69
- const { byteSrc: baseSrc, attrs: baseAttrs, attrsByteSize } = await this.getAttrsAndByteSrc(base);
70
- baseAttrsSize = (baseAttrs ? attrsByteSize : 0);
71
- if (baseAttrs) {
72
- initLayoutOfs = baseAttrs.getFileSize();
73
- if (typeof initLayoutOfs === 'number') {
74
- layout = file_layout_1.RWFileLayout.orderedWithBaseSize(initLayoutOfs);
75
- }
76
- else {
77
- initLayoutOfs = baseAttrs.getFileLayoutOfs();
78
- if (typeof initLayoutOfs !== 'number') {
79
- throw new Error(`File attributes have neither file size, nor pointer to layout`);
80
- }
81
- layout = await file_layout_1.RWFileLayout.readFromSrc(baseSrc, initLayoutOfs);
82
- }
83
- }
84
- else {
85
- const { size } = await baseSrc.getSize();
86
- initLayoutOfs = size;
87
- layout = file_layout_1.RWFileLayout.orderedWithBaseSize(size);
53
+ async readBytes(objSrc, start, end, getAttrs = false) {
54
+ if ((typeof start === 'number') && (start < 0)) {
55
+ throw new Error(`Parameter start has bad value: ${start}`);
56
+ }
57
+ if ((typeof end === 'number') && (end < 0)) {
58
+ throw new Error(`Parameter end has bad value: ${end}`);
59
+ }
60
+ const payload = await this.readonlyPayload(objSrc);
61
+ const size = payload.getAttrs().size;
62
+ if (start === undefined) {
63
+ start = 0;
64
+ end = size;
65
+ }
66
+ else if (start >= size) {
67
+ return (getAttrs ? { fileAttrs: await fileAttrsFrom(payload) } : {});
68
+ }
69
+ if (typeof end === 'number') {
70
+ end = Math.min(size, end);
71
+ if (end <= start) {
72
+ return (getAttrs ?
73
+ { fileAttrs: await fileAttrsFrom(payload) } : {});
88
74
  }
89
75
  }
90
76
  else {
91
- writer = await this.segWriter(version);
92
- baseAttrsSize = undefined;
93
- initLayoutOfs = undefined;
94
- layout = file_layout_1.RWFileLayout.orderedWithBaseSize(0);
77
+ end = size;
95
78
  }
96
- const { sink, sub: originalSub } = xsp_files_1.makeEncryptingByteSinkWithAttrs(writer, baseAttrsSize);
97
- const deferredFileSink = processes_1.defer();
98
- return {
99
- sub: obs => {
100
- const unsub = originalSub(obs);
101
- file_sink_1.FileSink.from(sink, attrs, layout).then(sink => deferredFileSink.resolve(sink), err => deferredFileSink.reject(err));
102
- return unsub;
103
- },
104
- sinkDef: deferredFileSink.promise,
105
- cancelSinkDef: deferredFileSink.reject
106
- };
79
+ const bytes = await payload.readSomeContentBytes(start, end);
80
+ return (getAttrs ?
81
+ { bytes, fileAttrs: await fileAttrsFrom(payload) } :
82
+ { bytes });
83
+ }
84
+ async saveBytes(bytes, version, attrs, xattrs) {
85
+ return super.writeWhole(bytes, version, attrs, xattrs);
86
+ }
87
+ async getFileSink(version, attrs, xattrs, base) {
88
+ return await super.writableSink(version, attrs, xattrs, base);
107
89
  }
108
90
  }
109
- Object.freeze(FileCrypto.prototype);
110
- Object.freeze(FileCrypto);
91
+ Object.freeze(FilePersistance.prototype);
92
+ Object.freeze(FilePersistance);
111
93
  class FileNode extends node_in_fs_1.NodeInFS {
112
94
  constructor(storage, fileName, objId, version, parentId, key) {
113
95
  super(storage, 'file', fileName, objId, version, parentId);
96
+ this.fileSize = 0;
114
97
  if (!fileName || !objId) {
115
98
  throw new Error("Bad file parameter(s) given");
116
99
  }
117
- this.crypto = new FileCrypto(xsp_files_1.idToHeaderNonce(this.objId), key, this.storage.cryptor);
100
+ this.crypto = new FilePersistance(xsp_files_1.idToHeaderNonce(this.objId), key, this.storage.cryptor);
118
101
  Object.seal(this);
119
102
  }
120
103
  static async makeForNew(storage, parentId, name, key) {
@@ -123,7 +106,7 @@ class FileNode extends node_in_fs_1.NodeInFS {
123
106
  }
124
107
  const objId = await storage.generateNewObjId();
125
108
  const file = new FileNode(storage, name, objId, 0, parentId, key);
126
- file.attrs = file_attrs_1.AttrsHolder.makeReadonlyForFile(Date.now());
109
+ file.attrs = attrs_1.CommonAttrs.makeForTimeNow();
127
110
  return file;
128
111
  }
129
112
  static async makeForExisting(storage, parentId, fileName, objId, key) {
@@ -142,47 +125,76 @@ class FileNode extends node_in_fs_1.NodeInFS {
142
125
  static async initWithAttrs(storage, parentId, fileName, objId, key) {
143
126
  const src = await storage.getObj(objId);
144
127
  const file = new FileNode(storage, fileName, objId, src.version, parentId, key);
145
- const { attrs } = await file.crypto.getAttrsAndByteSrc(src);
146
- file.attrs = (attrs ?
147
- attrs : file_attrs_1.AttrsHolder.makeReadonlyForFile(Date.now()));
128
+ const fileAttrs = await file.crypto.getAttrs(src);
129
+ file.setUpdatedState(src.version, fileAttrs);
148
130
  return file;
149
131
  }
132
+ setUpdatedState(version, fileAttrs) {
133
+ this.fileSize = fileAttrs.size;
134
+ super.setUpdatedParams(version, fileAttrs.attrs, fileAttrs.xattrs);
135
+ }
136
+ get size() {
137
+ return this.fileSize;
138
+ }
150
139
  async readSrc() {
151
140
  const objSrc = await this.storage.getObj(this.objId);
152
- const { fileSrc: src } = await this.crypto.decryptedBytesSource(objSrc);
153
- let version;
154
141
  if ((this.storage.type === 'synced') || (this.storage.type === 'local')) {
155
- version = objSrc.version;
142
+ const version = objSrc.version;
156
143
  if (this.version < version) {
157
- this.setCurrentVersion(version);
144
+ const { src, fileAttrs } = await this.crypto.getFileSource(objSrc, true);
145
+ this.setUpdatedState(version, fileAttrs);
146
+ return { src, version };
147
+ }
148
+ else {
149
+ const { src } = await this.crypto.getFileSource(objSrc);
150
+ return { src, version };
158
151
  }
159
152
  }
160
153
  else {
154
+ const { src } = await this.crypto.getFileSource(objSrc);
161
155
  // unversioned storage passes undefined version
162
- version = undefined;
156
+ return { src, version: undefined };
163
157
  }
164
- return { src, version };
165
158
  }
166
- async writeSink(truncate, currentVersion) {
159
+ async readBytes(start, end) {
160
+ const objSrc = await this.storage.getObj(this.objId);
161
+ if ((this.storage.type === 'synced') || (this.storage.type === 'local')) {
162
+ const version = objSrc.version;
163
+ if (this.version < version) {
164
+ const { bytes, fileAttrs } = await this.crypto.readBytes(objSrc, start, end, true);
165
+ this.setUpdatedState(version, fileAttrs);
166
+ return { bytes, version };
167
+ }
168
+ else {
169
+ const { bytes } = await this.crypto.readBytes(objSrc, start, end);
170
+ return { bytes, version };
171
+ }
172
+ }
173
+ else {
174
+ const { bytes } = await this.crypto.readBytes(objSrc, start, end);
175
+ // unversioned storage passes undefined version
176
+ return { bytes, version: undefined };
177
+ }
178
+ }
179
+ async writeSink(truncate, currentVersion, changes) {
167
180
  const deferredSink = processes_1.defer();
168
- let newVersion = 0; // need to set any value to satisfy compiler
181
+ const newSize = processes_1.defer();
182
+ let version = 0; // need to set any value to satisfy compiler
169
183
  const completion = this.doChange(false, async () => {
170
- const step1 = await this.startMakingSinkInsideChange(truncate, currentVersion).catch(err => {
171
- deferredSink.reject(err);
172
- throw err;
173
- });
174
- newVersion = step1.newVersion;
175
- deferredSink.resolve({ sinkPromise: step1.sinkDef });
176
- await this.savingObjInsideChange(step1.attrs, step1.newVersion, step1.sub).catch(err => {
177
- step1.cancelSinkDef(err);
178
- throw err;
179
- });
184
+ const { attrs, xattrs, newVersion, sinkPromise, sub } = await this.startMakingSinkInsideChange(truncate, currentVersion, changes);
185
+ version = newVersion;
186
+ deferredSink.resolve(sinkPromise);
187
+ await this.savingObjInsideChange(attrs, newSize.promise, xattrs, newVersion, sub);
180
188
  });
181
- // in case overall completion is never waited, if early error comes
182
- completion.catch(noop);
183
- // explicitly await two steps to get all possible errors
184
- const sDef = await deferredSink.promise; // after await newVersion is set
185
- const sink = await sDef.sinkPromise;
189
+ let sink = undefined;
190
+ // race allows to either get sink or threw possible errors from completion
191
+ await Promise.race([
192
+ deferredSink.promise.then(async (sinkPromise) => {
193
+ sink = await sinkPromise;
194
+ }),
195
+ completion
196
+ ]);
197
+ assert_1.assert(!!sink);
186
198
  // sink's done should await completion of obj saving, and
187
199
  // error in obj saving should cancel sink
188
200
  const originalDone = sink.done;
@@ -190,48 +202,48 @@ class FileNode extends node_in_fs_1.NodeInFS {
190
202
  assert_1.assert(!Object.isFrozen(sink), `Can't mutate frozen sink`);
191
203
  sink.done = async (err) => {
192
204
  if (err) {
205
+ newSize.resolve(0);
193
206
  await originalDone(err);
207
+ await completion.catch(noop);
194
208
  }
195
209
  else {
210
+ const size = await sink.getSize();
211
+ newSize.resolve(size);
196
212
  await originalDone();
197
213
  await completion;
198
214
  }
199
215
  };
200
- return {
201
- sink,
202
- version: newVersion
203
- };
216
+ return { sink, version };
204
217
  }
205
- async startMakingSinkInsideChange(truncate, currentVersion) {
218
+ async startMakingSinkInsideChange(truncate, currentVersion, changes) {
206
219
  if ((typeof currentVersion === 'number')
207
220
  && (this.version !== currentVersion)) {
208
221
  throw file_1.makeVersionMismatchExc(this.name);
209
222
  }
210
- const newVersion = this.version + 1;
211
- const attrs = this.attrs.modifiableCopy();
223
+ const { attrs, xattrs, newVersion } = super.getParamsForUpdate(changes);
212
224
  const base = ((truncate || (this.version === 0)) ?
213
225
  undefined :
214
226
  await this.storage.getObj(this.objId));
215
- const { sinkDef, sub, cancelSinkDef } = await this.crypto.encryptingByteSink(newVersion, attrs, base);
216
- return { attrs, newVersion, sinkDef, sub, cancelSinkDef };
227
+ const { sinkPromise, sub } = await this.crypto.getFileSink(newVersion, attrs, xattrs, base);
228
+ return { attrs, xattrs, newVersion, sinkPromise, sub };
217
229
  }
218
- async savingObjInsideChange(attrs, newVersion, encSub) {
230
+ async savingObjInsideChange(attrs, newSize, xattrs, newVersion, encSub) {
219
231
  await this.storage.saveObj(this.objId, newVersion, encSub);
220
- this.setCurrentVersion(newVersion);
221
- attrs.setReadonly();
222
- this.attrs = attrs;
232
+ const size = await newSize;
233
+ this.setUpdatedState(newVersion, { attrs, size, xattrs });
223
234
  this.broadcastEvent({
224
235
  type: 'file-change',
225
236
  path: this.name,
226
237
  newVersion
227
238
  });
228
239
  }
229
- save(bytes) {
240
+ save(bytes, changes) {
230
241
  return this.doChange(false, async () => {
231
- const newVersion = this.version + 1;
232
- const attrs = this.attrs.modifiableCopy();
233
- const encSub = await this.crypto.saveBytes(bytes, newVersion, attrs);
234
- await this.savingObjInsideChange(attrs, newVersion, encSub);
242
+ const { attrs, xattrs, newVersion } = super.getParamsForUpdate(changes);
243
+ const encSub = await this.crypto.saveBytes(bytes, newVersion, attrs, xattrs);
244
+ const newSize = Promise.resolve(Array.isArray(bytes) ?
245
+ buffer_utils_1.byteLengthIn(bytes) : bytes.length);
246
+ await this.savingObjInsideChange(attrs, newSize, xattrs, newVersion, encSub);
235
247
  return this.version;
236
248
  });
237
249
  }
@@ -10,7 +10,6 @@ declare type Observer<T> = web3n.Observer<T>;
10
10
  declare type FileByteSource = web3n.files.FileByteSource;
11
11
  declare type FileByteSink = web3n.files.FileByteSink;
12
12
  declare type XAttrsChanges = web3n.files.XAttrsChanges;
13
- export declare function readBytesFrom(src: FileByteSource, start: number | undefined, end: number | undefined): Promise<Uint8Array | undefined>;
14
13
  export declare class FileObject implements WritableFile, Linkable {
15
14
  name: string;
16
15
  isNew: boolean;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /*
3
- Copyright (C) 2016 - 2020 3NSoft Inc.
3
+ Copyright (C) 2016 - 2020, 2022 3NSoft Inc.
4
4
 
5
5
  This program is free software: you can redistribute it and/or modify it under
6
6
  the terms of the GNU General Public License as published by the Free Software
@@ -13,9 +13,10 @@
13
13
  See the GNU General Public License for more details.
14
14
 
15
15
  You should have received a copy of the GNU General Public License along with
16
- this program. If not, see <http://www.gnu.org/licenses/>. */
16
+ this program. If not, see <http://www.gnu.org/licenses/>.
17
+ */
17
18
  Object.defineProperty(exports, "__esModule", { value: true });
18
- exports.FileObject = exports.readBytesFrom = void 0;
19
+ exports.FileObject = void 0;
19
20
  /**
20
21
  * Everything in this module is assumed to be inside of a file system
21
22
  * reliance set.
@@ -25,46 +26,6 @@ const files_1 = require("../../files");
25
26
  const file_node_1 = require("./file-node");
26
27
  const buffer_utils_1 = require("../../../lib-common/buffer-utils");
27
28
  const pipe_1 = require("../../../lib-common/byte-streaming/pipe");
28
- async function readBytesFrom(src, start, end) {
29
- if ((typeof start === 'number') && (start < 0)) {
30
- throw new Error(`Parameter start has bad value: ${start}`);
31
- }
32
- if ((typeof end === 'number') && (end < 0)) {
33
- throw new Error(`Parameter end has bad value: ${end}`);
34
- }
35
- const size = await src.getSize();
36
- if (typeof size !== 'number') {
37
- throw new Error('File size is not known.');
38
- }
39
- if (size === 0) {
40
- return;
41
- }
42
- if (typeof start === 'number') {
43
- if (start >= size) {
44
- return;
45
- }
46
- if (typeof end === 'number') {
47
- end = Math.min(size, end);
48
- if (end <= start) {
49
- return;
50
- }
51
- }
52
- else {
53
- end = size;
54
- }
55
- if (!src.seek) {
56
- throw new Error('Byte source is not seekable.');
57
- }
58
- await src.seek(start);
59
- const bytes = await src.read(end - start);
60
- return bytes;
61
- }
62
- else {
63
- const bytes = await src.read(undefined);
64
- return bytes;
65
- }
66
- }
67
- exports.readBytesFrom = readBytesFrom;
68
29
  class FileObject {
69
30
  constructor(name, isNew, node, makeOrGetNode, writable) {
70
31
  this.name = name;
@@ -99,11 +60,14 @@ class FileObject {
99
60
  if (!this.v.node) {
100
61
  throw file_1.makeFileException(file_1.Code.notFound, this.name);
101
62
  }
102
- const { src } = await this.v.node.readSrc();
63
+ const attrs = this.v.node.getAttrs();
103
64
  const stat = {
104
65
  writable: this.writable,
105
- size: await src.getSize(),
106
- version: this.v.node.version
66
+ size: this.v.node.size,
67
+ version: this.v.node.version,
68
+ isFile: true,
69
+ ctime: new Date(attrs.ctime),
70
+ mtime: new Date(attrs.mtime),
107
71
  };
108
72
  return stat;
109
73
  }
@@ -226,9 +190,10 @@ class V {
226
190
  return this.writeTxt(JSON.stringify(json));
227
191
  }
228
192
  async readBytes(start, end) {
229
- const { src, version } = await this.getByteSource();
230
- const bytes = await readBytesFrom(src, start, end);
231
- return { bytes, version };
193
+ if (!this.node) {
194
+ throw file_1.makeFileException(file_1.Code.notFound, this.name);
195
+ }
196
+ return await this.node.readBytes(start, end);
232
197
  }
233
198
  async readTxt() {
234
199
  const { bytes, version } = await this.readBytes();
@@ -1,3 +1,3 @@
1
1
  import { FolderInfo } from './folder-node';
2
+ export declare function parseFolderInfo(bytes: Uint8Array | undefined): FolderInfo;
2
3
  export declare function serializeFolderInfo(folderInfo: FolderInfo): Uint8Array[];
3
- export declare function deserializeFolderInfo(bytes: Uint8Array): FolderInfo;