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,456 +0,0 @@
1
- "use strict";
2
- /*
3
- Copyright (C) 2020 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
- Object.defineProperty(exports, "__esModule", { value: true });
18
- exports.fileLayoutException = exports.RWFileLayout = exports.ROFileLayout = void 0;
19
- const assert_1 = require("../../lib-common/assert");
20
- const big_endian_1 = require("../../lib-common/big-endian");
21
- const json_utils_1 = require("../../lib-common/json-utils");
22
- class ROFileLayout {
23
- constructor(sections, layoutOfs) {
24
- this.sections = sections;
25
- this.layoutOfs = layoutOfs;
26
- Object.freeze(this);
27
- }
28
- static orderedWithSize(size) {
29
- return new ROFileLayout(continuousSections(size), size);
30
- }
31
- static async readFromSrc(src, layoutOfs) {
32
- const sections = await readSectionsFrom(src, layoutOfs);
33
- return new ROFileLayout(sections, layoutOfs);
34
- }
35
- get contentSize() {
36
- return sizeOfSections(this.sections);
37
- }
38
- getSectionsIn(ofs, len) {
39
- return getSectionsIn(this.sections, ofs, len);
40
- }
41
- makeWritableClone() {
42
- return new RWFileLayout(json_utils_1.copy(this.sections), this.layoutOfs);
43
- }
44
- }
45
- exports.ROFileLayout = ROFileLayout;
46
- Object.freeze(ROFileLayout.prototype);
47
- Object.freeze(ROFileLayout);
48
- function sizeOfSections(sections) {
49
- if (sections.length === 0) {
50
- return 0;
51
- }
52
- const last = sections[sections.length - 1];
53
- return (last.ofs + last.len);
54
- }
55
- function continuousSections(size) {
56
- assert_1.assert(Number.isInteger(size) && (size >= 0));
57
- return ((size === 0) ? [] : [{ ofsInSrc: 0, ofs: 0, len: size }]);
58
- }
59
- function getSectionsIn(sections, ofs, len) {
60
- assert_1.assert(Number.isInteger(ofs) && (ofs >= 0));
61
- assert_1.assert((len === undefined) || (Number.isInteger(len) && (len >= 0)));
62
- const contentSize = sizeOfSections(sections);
63
- if ((contentSize <= ofs) || (len === 0)) {
64
- return [];
65
- }
66
- const fstInd = sections.findIndex(s => ((s.ofs <= ofs) && (ofs < (s.ofs + s.len))));
67
- const s = [copySectionMovingOfs(sections[fstInd], ofs)];
68
- const end = ((len === undefined) ? undefined : ofs + len);
69
- const lastInd = (((end === undefined) || (end >= contentSize)) ?
70
- sections.length - 1 :
71
- sections.findIndex(s => (end <= (s.ofs + s.len))));
72
- for (let i = (fstInd + 1); i <= lastInd; i += 1) {
73
- s.push(json_utils_1.copy(sections[i]));
74
- }
75
- if (end !== undefined) {
76
- const last = s[s.length - 1];
77
- const sEnd = last.ofs + last.len;
78
- if (end < sEnd) {
79
- last.len -= sEnd - end;
80
- }
81
- }
82
- return s;
83
- }
84
- /**
85
- * This layout expects that writes of new bytes always append raw source,
86
- * while cuts in raw source remove base bytes, but don't remove already written
87
- * new bytes, leaving them as noise.
88
- */
89
- class RWFileLayout {
90
- constructor(sections, srcBaseLen) {
91
- this.sections = sections;
92
- this.srcBaseLen = srcBaseLen;
93
- this.writePosition = this.srcBaseLen;
94
- Object.seal(this);
95
- }
96
- static orderedWithBaseSize(size) {
97
- return new RWFileLayout(continuousSections(size), size);
98
- }
99
- static async readFromSrc(src, layoutOfs) {
100
- const sections = await readSectionsFrom(src, layoutOfs);
101
- return new RWFileLayout(sections, layoutOfs);
102
- }
103
- get contentSize() {
104
- return sizeOfSections(this.sections);
105
- }
106
- getSectionsIn(ofs, len) {
107
- return getSectionsIn(this.sections, ofs, len);
108
- }
109
- getLayoutOfsInSink() {
110
- return this.writePosition;
111
- }
112
- packIfNotTrivial(sinkLen) {
113
- return (this.isTrivialLayout(sinkLen.size, sinkLen.isEndless) ?
114
- undefined : packSections(this.sections));
115
- }
116
- isTrivialLayout(sinkSize, isSinkEndless) {
117
- if (isSinkEndless) {
118
- return false;
119
- }
120
- if (this.sections.length === 0) {
121
- return (sinkSize === 0);
122
- }
123
- else if (this.sections.length === 1) {
124
- const s = this.sections[0];
125
- return ((s.ofsInSrc === 0) && (s.ofs === 0) && (s.len === sinkSize));
126
- }
127
- else {
128
- return false;
129
- }
130
- }
131
- toFileLayoutBasedOnSegs(segs) {
132
- const l = { sections: [] };
133
- if (typeof segs.base !== 'number') {
134
- l.base = segs.base;
135
- }
136
- for (const s of this.sections) {
137
- if (typeof s.ofsInSrc === 'number') {
138
- l.sections.push(...contentSectionsInSegs(segs.sections, s.ofsInSrc, s.ofs, s.len));
139
- }
140
- else {
141
- l.sections.push({ src: 'empty', ofs: s.ofs, len: s.len });
142
- }
143
- }
144
- compressLayoutSections(l.sections);
145
- return l;
146
- }
147
- findOffsetPosition(ofs) {
148
- for (let ind = 0; ind < this.sections.length; ind += 1) {
149
- const s = this.sections[ind];
150
- if ((s.ofs <= ofs) && (ofs < (s.ofs + s.len))) {
151
- return { s, ind, sOfs: ofs - s.ofs };
152
- }
153
- }
154
- return;
155
- }
156
- cutSection(ofs, len) {
157
- const left = this.findOffsetPosition(ofs);
158
- if (!left) {
159
- return [];
160
- }
161
- const right = this.findOffsetPosition(ofs + len);
162
- if (!right) {
163
- let cuts;
164
- if (left.sOfs === 0) {
165
- cuts = this.sections.splice(left.ind, this.sections.length);
166
- }
167
- else {
168
- cuts = this.sections.splice(left.ind + 1, this.sections.length);
169
- const cutOnLeft = cutTailOf(left.s, left.sOfs);
170
- cuts.push(cutOnLeft);
171
- }
172
- return this.turnToBaseCutsAdjustingSrcOfs(cuts);
173
- }
174
- if (left.s === right.s) {
175
- let cuts;
176
- if (left.sOfs === 0) {
177
- cuts = [cutHeadOf(left.s, right.sOfs)];
178
- this.shiftSectonOffsets(left.ind, -len);
179
- }
180
- else {
181
- const newRight = cutTailOf(left.s, right.sOfs);
182
- cuts = [cutTailOf(left.s, left.sOfs)];
183
- this.sections.splice(left.ind + 1, 0, newRight);
184
- this.shiftSectonOffsets(left.ind + 1, -len);
185
- }
186
- this.checkAndCompactFourSections(Math.max(left.ind - 1, 0));
187
- return this.turnToBaseCutsAdjustingSrcOfs(cuts);
188
- }
189
- let cuts;
190
- if (left.sOfs === 0) {
191
- cuts = this.sections.splice(left.ind, right.ind - left.ind);
192
- if (right.sOfs > 0) {
193
- const cutOnRight = cutHeadOf(right.s, right.sOfs);
194
- cuts.push(cutOnRight);
195
- }
196
- this.shiftSectonOffsets(left.ind, -len);
197
- }
198
- else {
199
- cuts = this.sections.splice(left.ind + 1, right.ind - left.ind - 1);
200
- const cutOnLeft = cutTailOf(left.s, left.sOfs);
201
- cuts.push(cutOnLeft);
202
- if (right.sOfs > 0) {
203
- const cutOnRight = cutHeadOf(right.s, right.sOfs);
204
- cuts.push(cutOnRight);
205
- }
206
- this.shiftSectonOffsets(left.ind + 1, -len);
207
- }
208
- this.checkAndCompactFourSections(Math.max(left.ind - 1, 0));
209
- return this.turnToBaseCutsAdjustingSrcOfs(cuts);
210
- }
211
- shiftSectonOffsets(fromInd, delta) {
212
- for (let i = fromInd; i < this.sections.length; i += 1) {
213
- this.sections[i].ofs += delta;
214
- }
215
- }
216
- turnToBaseCutsAdjustingSrcOfs(cuts) {
217
- const baseSections = [];
218
- let totalCutLen = 0;
219
- for (const s of cuts) {
220
- if ((typeof s.ofsInSrc === 'number')
221
- && (s.ofsInSrc < this.srcBaseLen)) {
222
- const cut = {
223
- len: Math.min(s.len, this.srcBaseLen - s.ofsInSrc),
224
- ofs: s.ofsInSrc
225
- };
226
- baseSections.push(cut);
227
- totalCutLen += cut.len;
228
- }
229
- }
230
- this.srcBaseLen -= totalCutLen;
231
- this.writePosition -= totalCutLen;
232
- assert_1.assert(this.srcBaseLen >= 0);
233
- for (const b of baseSections) {
234
- for (const s of this.sections) {
235
- if ((typeof s.ofsInSrc === 'number') && (b.ofs < s.ofsInSrc)) {
236
- s.ofsInSrc -= b.len;
237
- assert_1.assert(s.ofsInSrc >= 0);
238
- }
239
- }
240
- }
241
- return baseSections;
242
- }
243
- checkAndCompactFourSections(startInd) {
244
- for (let i = 0; i < 3; i += 1) {
245
- const leftInd = startInd + i;
246
- const rightInd = leftInd + 1;
247
- if (rightInd >= this.sections.length) {
248
- return;
249
- }
250
- const left = this.sections[leftInd];
251
- const right = this.sections[rightInd];
252
- assert_1.assert(((left.ofs + left.len) === right.ofs) && (right.len > 0));
253
- if (left.ofsInSrc === undefined) {
254
- if (right.ofsInSrc !== undefined) {
255
- continue;
256
- }
257
- }
258
- else {
259
- if ((right.ofsInSrc === undefined)
260
- || ((left.ofsInSrc + left.len) !== right.ofsInSrc)) {
261
- continue;
262
- }
263
- }
264
- left.len += right.len;
265
- this.sections.splice(rightInd, 1);
266
- i -= 1;
267
- }
268
- }
269
- appendEmptySection(len) {
270
- if (this.sections.length > 0) {
271
- const lastSec = this.sections[this.sections.length - 1];
272
- if (typeof lastSec.ofsInSrc !== 'number') {
273
- lastSec.len += len;
274
- }
275
- else {
276
- this.sections.push({ ofs: (lastSec.ofs + lastSec.len), len });
277
- }
278
- }
279
- else {
280
- this.sections.push({ ofs: 0, len });
281
- }
282
- }
283
- insertSection(ofs, len) {
284
- const initContentSize = this.contentSize;
285
- const ofsInSrc = this.writePosition;
286
- this.writePosition += len;
287
- // adding at the end
288
- if (initContentSize <= ofs) {
289
- const gapLen = ofs - initContentSize;
290
- if (gapLen > 0) {
291
- this.appendEmptySection(gapLen);
292
- }
293
- this.sections.push({ ofs, len, ofsInSrc });
294
- if (this.sections.length >= 2) {
295
- this.checkAndCompactFourSections(this.sections.length - 2);
296
- }
297
- return ofsInSrc;
298
- }
299
- // inserting inside
300
- const insPos = this.findOffsetPosition(ofs);
301
- if (!insPos) {
302
- throw new Error(`Can't find ofs=${ofs} in sections`);
303
- }
304
- const newSection = { ofs, len, ofsInSrc };
305
- if (insPos.sOfs === 0) {
306
- this.sections.splice(insPos.ind, 0, newSection);
307
- this.shiftSectonOffsets(insPos.ind + 1, len);
308
- }
309
- else {
310
- const left = insPos.s;
311
- const right = cutTailOf(left, insPos.sOfs);
312
- this.sections.splice(insPos.ind + 1, 0, newSection, right);
313
- this.shiftSectonOffsets(insPos.ind + 2, len);
314
- }
315
- this.checkAndCompactFourSections(Math.max(0, insPos.ind - 1));
316
- return ofsInSrc;
317
- }
318
- }
319
- exports.RWFileLayout = RWFileLayout;
320
- Object.freeze(RWFileLayout.prototype);
321
- Object.freeze(RWFileLayout);
322
- function cutHeadOf(s, sOfs) {
323
- const head = {
324
- len: sOfs,
325
- ofs: s.ofs,
326
- ofsInSrc: ((typeof s.ofsInSrc === 'number') ? s.ofsInSrc : undefined)
327
- };
328
- s.len -= head.len;
329
- s.ofs += head.len;
330
- if (typeof s.ofsInSrc === 'number') {
331
- s.ofsInSrc += head.len;
332
- }
333
- return head;
334
- }
335
- function cutTailOf(s, sOfs) {
336
- const tail = {
337
- len: s.len - sOfs,
338
- ofs: s.ofs + sOfs,
339
- ofsInSrc: ((typeof s.ofsInSrc === 'number') ?
340
- s.ofsInSrc + sOfs : undefined)
341
- };
342
- s.len = sOfs;
343
- return tail;
344
- }
345
- function fileLayoutException(msg, cause) {
346
- return {
347
- runtimeException: true,
348
- type: 'file-layout',
349
- cause, msg
350
- };
351
- }
352
- exports.fileLayoutException = fileLayoutException;
353
- async function readSectionsFrom(src, layoutOfs) {
354
- const initPos = await src.getPosition();
355
- await src.seek(layoutOfs);
356
- const bytes = await src.read(undefined);
357
- await src.seek(initPos);
358
- if (!bytes) {
359
- throw fileLayoutException(`Reading at layout offset ${layoutOfs} produces no bytes (EOF?)`);
360
- }
361
- return parseSectionsFrom(bytes);
362
- }
363
- function parseSectionsFrom(bytes) {
364
- if (bytes.length < 8) {
365
- throw fileLayoutException(`Array len ${bytes.length} is too short for layout parsing`);
366
- }
367
- const expectedLen = big_endian_1.uintFrom8Bytes(bytes, 0);
368
- if ((bytes.length - 8) < expectedLen) {
369
- throw fileLayoutException(`Array len ${bytes.length - 8} is shorter than expected layout ${expectedLen}`);
370
- }
371
- const sections = [];
372
- let i = 8;
373
- let ofs = 0;
374
- while (i < bytes.length) {
375
- const ofsInStr = uintOrUndefinedFrom8Bytes(bytes, i);
376
- i += 8;
377
- const len = big_endian_1.uintFrom8Bytes(bytes, i);
378
- i += 8;
379
- sections.push({ ofsInSrc: ofsInStr, len, ofs });
380
- ofs += len;
381
- }
382
- return sections;
383
- }
384
- function packSections(sections) {
385
- const sectionsPackLen = 16 * sections.length;
386
- const bytes = Buffer.allocUnsafe(8 + sectionsPackLen);
387
- big_endian_1.packUintTo8Bytes(sectionsPackLen, bytes, 0);
388
- let i = 8;
389
- for (const s of sections) {
390
- packUintOrUndefinedInto8Bytes(s.ofsInSrc, bytes, i);
391
- i += 8;
392
- big_endian_1.packUintTo8Bytes(s.len, bytes, i);
393
- i += 8;
394
- }
395
- return bytes;
396
- }
397
- const UNINIT_OFS_VALUE = Buffer.alloc(8, 0xff);
398
- function uintOrUndefinedFrom8Bytes(bytes, i) {
399
- for (let b = 0; b < 8; b += 1) {
400
- if (bytes[i + b] !== 0xff) {
401
- return big_endian_1.uintFrom8Bytes(bytes, i);
402
- }
403
- }
404
- return;
405
- }
406
- function packUintOrUndefinedInto8Bytes(u, bytes, i) {
407
- if (typeof u === 'number') {
408
- big_endian_1.packUintTo8Bytes(u, bytes, i);
409
- }
410
- else {
411
- bytes.set(UNINIT_OFS_VALUE, i);
412
- }
413
- }
414
- function copySectionMovingOfs(sec, newOfs) {
415
- const ofsDelta = newOfs - sec.ofs;
416
- const copy = {
417
- ofs: newOfs,
418
- len: sec.len - ofsDelta,
419
- };
420
- if (typeof sec.ofsInSrc === 'number') {
421
- copy.ofsInSrc = sec.ofsInSrc + ofsDelta;
422
- }
423
- return copy;
424
- }
425
- function contentSectionsInSegs(segs, segsOfs, contentOfs, contentLen) {
426
- const fstSegInd = segs.findIndex(s => (typeof s.len !== 'number') || (segsOfs < (s.ofs + s.len)));
427
- assert_1.assert(fstSegInd >= 0);
428
- let i = fstSegInd;
429
- const ls = [];
430
- while (contentLen > 0) {
431
- const seg = segs[i];
432
- const len = (typeof seg.len !== 'number') ?
433
- contentLen : Math.min(contentLen, seg.len);
434
- ls.push({ src: seg.src, ofs: contentOfs, len });
435
- contentOfs += len;
436
- contentLen -= len;
437
- i += 1;
438
- }
439
- return ls;
440
- }
441
- function compressLayoutSections(sections) {
442
- if (sections.length === 0) {
443
- return;
444
- }
445
- let prev = sections[0];
446
- for (let i = 1; i < sections.length; i += 1) {
447
- const s = sections[i];
448
- if (prev.src === s.src) {
449
- prev.len += s.len;
450
- sections.splice(i, 1);
451
- i -= 1;
452
- }
453
- prev = s;
454
- }
455
- }
456
- Object.freeze(exports);
@@ -1,33 +0,0 @@
1
- import { FileAttrs, AttrsHolder } from "./file-attrs";
2
- import { RWFileLayout } from "./file-layout";
3
- import { ByteSinkWithAttrs } from "xsp-files";
4
- declare type FileByteSink = web3n.files.FileByteSink;
5
- declare type FileLayout = web3n.files.FileLayout;
6
- /**
7
- * This implementation of a sink will put new bytes at the end of the raw sink.
8
- * Mapping from out-of-order writes to linear recording is captured in file
9
- * layout that is recorded after all bytes are written and placed at after all
10
- * bytes. Layout offset is written into attributes. If file layout is trivial,
11
- * i.e. all positions in raw sink correspond to file positions, it isn't written
12
- * and attributes have no layout offset.
13
- */
14
- export declare class FileSink implements FileByteSink {
15
- private readonly rawSink;
16
- private readonly layout;
17
- private readonly attrs;
18
- private err;
19
- private isDone;
20
- private constructor();
21
- static from(sink: ByteSinkWithAttrs, attrs: AttrsHolder<FileAttrs>, layout: RWFileLayout): Promise<FileByteSink>;
22
- getSize(): Promise<number>;
23
- private throwUpIfDone;
24
- private errThis;
25
- showLayout(): Promise<FileLayout>;
26
- truncate(size: number): Promise<void>;
27
- splice(pos: number, del: number, bytes?: Uint8Array): Promise<void>;
28
- private appendContentToRawSink;
29
- private deleteBytes;
30
- done(err?: any): Promise<void>;
31
- private saveLayoutAndAttrs;
32
- }
33
- export {};
@@ -1,173 +0,0 @@
1
- "use strict";
2
- /*
3
- Copyright (C) 2020 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
- Object.defineProperty(exports, "__esModule", { value: true });
18
- exports.FileSink = void 0;
19
- const wrapping_1 = require("../../lib-common/byte-streaming/wrapping");
20
- const assert_1 = require("../../lib-common/assert");
21
- const error_1 = require("../../lib-common/exceptions/error");
22
- /**
23
- * This implementation of a sink will put new bytes at the end of the raw sink.
24
- * Mapping from out-of-order writes to linear recording is captured in file
25
- * layout that is recorded after all bytes are written and placed at after all
26
- * bytes. Layout offset is written into attributes. If file layout is trivial,
27
- * i.e. all positions in raw sink correspond to file positions, it isn't written
28
- * and attributes have no layout offset.
29
- */
30
- class FileSink {
31
- constructor(rawSink, layout, attrs) {
32
- this.rawSink = rawSink;
33
- this.layout = layout;
34
- this.attrs = attrs;
35
- this.err = undefined;
36
- this.isDone = false;
37
- Object.seal(this);
38
- }
39
- static async from(sink, attrs, layout) {
40
- await sink.setAttrSectionSize(attrs.serializedLen);
41
- await sink.setSize(layout.getLayoutOfsInSink());
42
- const fileSink = new FileSink(sink, layout, attrs);
43
- return wrapping_1.wrapAndSyncFileSink(fileSink);
44
- }
45
- async getSize() {
46
- return this.layout.contentSize;
47
- }
48
- throwUpIfDone() {
49
- if (this.isDone) {
50
- if (this.err) {
51
- throw error_1.errWithCause(this.err, `File sink has already erred`);
52
- }
53
- else {
54
- throw new Error(`File sink is already done`);
55
- }
56
- }
57
- }
58
- async errThis(err) {
59
- if (this.err) {
60
- return;
61
- }
62
- this.err = err;
63
- await this.rawSink.done(this.err);
64
- this.isDone = true;
65
- }
66
- async showLayout() {
67
- const segs = await this.rawSink.showLayout();
68
- return this.layout.toFileLayoutBasedOnSegs(segs);
69
- }
70
- async truncate(size) {
71
- assert_1.assert(Number.isInteger(size) && (size >= 0), `Invalid size given: ${size}`);
72
- this.throwUpIfDone();
73
- try {
74
- const delta = size - this.layout.contentSize;
75
- if (delta < 0) {
76
- await this.deleteBytes(size, -delta);
77
- }
78
- else if (delta > 0) {
79
- this.layout.appendEmptySection(delta);
80
- }
81
- }
82
- catch (err) {
83
- await this.errThis(err);
84
- throw err;
85
- }
86
- }
87
- async splice(pos, del, bytes) {
88
- assert_1.assert(Number.isInteger(pos) && (pos >= 0)
89
- && Number.isInteger(del) && (del >= 0), `Invalid arguments given: pos=${pos}, del=${del}`);
90
- this.throwUpIfDone();
91
- const ins = (bytes ? bytes.length : 0);
92
- if ((del === 0) && (ins === 0)) {
93
- return;
94
- }
95
- try {
96
- if (this.layout.contentSize <= pos) {
97
- if (ins === 0) {
98
- return;
99
- }
100
- await this.appendContentToRawSink(pos, bytes);
101
- }
102
- else {
103
- if (del > 0) {
104
- await this.deleteBytes(pos, del);
105
- }
106
- if (ins > 0) {
107
- await this.appendContentToRawSink(pos, bytes);
108
- }
109
- }
110
- }
111
- catch (err) {
112
- await this.errThis(err);
113
- throw err;
114
- }
115
- }
116
- async appendContentToRawSink(pos, bytes) {
117
- const ins = bytes.length;
118
- const writePosition = this.layout.insertSection(pos, ins);
119
- await this.rawSink.spliceLayout(writePosition, ins, ins);
120
- await this.rawSink.write(writePosition, bytes);
121
- }
122
- async deleteBytes(pos, len) {
123
- // Note 1: only base section are given for removal from sink. New bytes
124
- // become noise, cause we can't reliably splice them.
125
- // Note 2: there are no explicit records for noise sections, cause this
126
- // information is recoverable.
127
- const rmSegs = this.layout.cutSection(pos, len);
128
- if (rmSegs.length === 0) {
129
- return;
130
- }
131
- rmSegs.sort((a, b) => a.ofs - b.ofs);
132
- for (let i = (rmSegs.length - 1); i >= 0; i -= 1) {
133
- const s = rmSegs[i];
134
- await this.rawSink.spliceLayout(s.ofs, s.len, 0);
135
- }
136
- }
137
- async done(err) {
138
- if (this.isDone) {
139
- if (!err && this.err) {
140
- throw error_1.errWithCause(this.err, `File sink has already erred`);
141
- }
142
- return;
143
- }
144
- if (err) {
145
- await this.errThis(err);
146
- return;
147
- }
148
- await this.saveLayoutAndAttrs().catch(async (err) => {
149
- await this.errThis(err);
150
- throw err;
151
- });
152
- await this.rawSink.done();
153
- this.isDone = true;
154
- }
155
- async saveLayoutAndAttrs() {
156
- const sinkLen = await this.rawSink.getSize();
157
- const layoutOfs = this.layout.getLayoutOfsInSink();
158
- const bytes = this.layout.packIfNotTrivial(sinkLen);
159
- if (bytes) {
160
- this.attrs.setFileLayoutOfs(layoutOfs);
161
- await this.rawSink.setSize(layoutOfs + bytes.length);
162
- await this.rawSink.write(layoutOfs, bytes);
163
- }
164
- else {
165
- this.attrs.setContinuousFileSize(layoutOfs);
166
- }
167
- await this.rawSink.writeAttrs(this.attrs.toBytes());
168
- }
169
- }
170
- exports.FileSink = FileSink;
171
- Object.freeze(FileSink.prototype);
172
- Object.freeze(FileSink);
173
- Object.freeze(exports);
@@ -1,19 +0,0 @@
1
- import { AttrsHolder, FileAttrs } from "./file-attrs";
2
- import { ByteSource } from "xsp-files";
3
- declare type FileByteSource = web3n.files.FileByteSource;
4
- declare type FileSection = web3n.files.FileSection;
5
- export declare class FileBytes implements FileByteSource {
6
- private readonly rawSrc;
7
- private readonly layout;
8
- private pos;
9
- private constructor();
10
- static from(src: ByteSource, attrs: AttrsHolder<FileAttrs> | undefined): Promise<FileByteSource>;
11
- getFileSections(ofs: number, len: number): FileSection[];
12
- read(len: number | undefined): Promise<Uint8Array | undefined>;
13
- private getSectionBytes;
14
- getSize(): Promise<number>;
15
- seek(offset: number): Promise<void>;
16
- getPosition(): Promise<number>;
17
- }
18
- export declare function fileSrcFromContinuousSrc(src: ByteSource): FileByteSource;
19
- export {};