@ethersphere/bee-js 12.0.0 → 12.2.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/dist/mjs/bee.js CHANGED
@@ -1733,16 +1733,15 @@ export class Bee {
1733
1733
  /**
1734
1734
  * Calculates the `amount` and expected duration extension for topping up a postage batch with a given BZZ value.
1735
1735
  *
1736
- * @param postageBatchId
1736
+ * @param depth Depth of the postage batch to top up.
1737
1737
  * @param bzz The amount of BZZ to spend on the top-up.
1738
1738
  * @param requestOptions Options for making requests, such as timeouts, custom HTTP agents, headers, etc.
1739
1739
  * @returns An object with `amount` (to pass to {@link topUpBatch}) and `duration` (the expected TTL extension).
1740
1740
  */
1741
- async calculateTopUpForBzz(postageBatchId, bzz, requestOptions) {
1742
- const batch = await this.getPostageBatch(postageBatchId, requestOptions);
1741
+ async calculateTopUpForBzz(depth, bzz, requestOptions) {
1743
1742
  const chainState = await this.getChainState(requestOptions);
1744
1743
  const blockTime = this.network === 'gnosis' ? 5 : 15;
1745
- const amount = bzz.toPLURBigInt() / 2n ** BigInt(batch.depth);
1744
+ const amount = bzz.toPLURBigInt() / 2n ** BigInt(depth);
1746
1745
  const duration = getStampDuration(amount, chainState.currentPrice, blockTime);
1747
1746
  return {
1748
1747
  amount,
@@ -12,10 +12,20 @@ export class TarStream {
12
12
  });
13
13
  }
14
14
  beginFile(path, size) {
15
- if (path.length > 100) {
16
- throw new Error(`File name too long: ${path}`);
15
+ const {
16
+ name,
17
+ prefix,
18
+ longLink
19
+ } = splitPath(path);
20
+ if (longLink) {
21
+ const encoder = new TextEncoder();
22
+ const pathData = encoder.encode(path + '\0');
23
+ this.pieces.push(createLongLinkHeader(pathData.length));
24
+ this.pieces.push(pathData);
25
+ const padding = pathData.length % 512 === 0 ? 0 : 512 - pathData.length % 512;
26
+ if (padding > 0) this.pieces.push(new Uint8Array(padding));
17
27
  }
18
- const header = createHeader(path, size);
28
+ const header = createHeader(name, prefix, size);
19
29
  this.pieces.push(header);
20
30
  this.currentFileSize = 0;
21
31
  }
@@ -33,7 +43,55 @@ export class TarStream {
33
43
  this.pieces.push(createEndOfArchive());
34
44
  }
35
45
  }
36
- function createHeader(path, size) {
46
+ function splitPath(path) {
47
+ if (path.length <= 100) return {
48
+ name: path,
49
+ prefix: '',
50
+ longLink: false
51
+ };
52
+ for (let i = path.length - 1; i >= 0; i--) {
53
+ if (path[i] === '/') {
54
+ const name = path.substring(i + 1);
55
+ const prefix = path.substring(0, i);
56
+ if (name.length <= 100 && prefix.length <= 155) return {
57
+ name,
58
+ prefix,
59
+ longLink: false
60
+ };
61
+ }
62
+ }
63
+ // Filename itself is > 100 chars or path > 255 chars — use GNU LongLink
64
+ const lastSlash = path.lastIndexOf('/');
65
+ const truncatedName = (lastSlash >= 0 ? path.substring(lastSlash + 1) : path).slice(0, 100);
66
+ return {
67
+ name: truncatedName,
68
+ prefix: '',
69
+ longLink: true
70
+ };
71
+ }
72
+ function createLongLinkHeader(size) {
73
+ const encoder = new TextEncoder();
74
+ function writeToBuffer(str, offset, length) {
75
+ const bytes = encoder.encode(str);
76
+ header.set(bytes.slice(0, length), offset);
77
+ }
78
+ const header = new Uint8Array(512);
79
+ header.fill(0);
80
+ writeToBuffer('././@LongLink', 0, 100);
81
+ writeToBuffer('0000644\0', 100, 8);
82
+ writeToBuffer('0000000\0', 108, 8);
83
+ writeToBuffer('0000000\0', 116, 8);
84
+ writeToBuffer(size.toString(8).padStart(11, '0') + '\0', 124, 12);
85
+ writeToBuffer('00000000000\0', 136, 12);
86
+ writeToBuffer(' ', 148, 8);
87
+ writeToBuffer('L', 156, 1);
88
+ writeToBuffer('ustar\0\0', 257, 8);
89
+ let checksum = 0;
90
+ for (let i = 0; i < 512; i++) checksum += header[i];
91
+ writeToBuffer(checksum.toString(8).padStart(6, '0') + '\0 ', 148, 8);
92
+ return header;
93
+ }
94
+ function createHeader(name, prefix, size) {
37
95
  const encoder = new TextEncoder();
38
96
  function writeToBuffer(str, offset, length) {
39
97
  const bytes = encoder.encode(str);
@@ -43,7 +101,7 @@ function createHeader(path, size) {
43
101
  const header = new Uint8Array(512);
44
102
  header.fill(0, 0, 512);
45
103
  // File name, truncated to 100 characters if necessary
46
- writeToBuffer(path.slice(0, 100).padEnd(100, '\0'), 0, 100);
104
+ writeToBuffer(name.slice(0, 100).padEnd(100, '\0'), 0, 100);
47
105
  // File mode (octal) and null-terminated
48
106
  writeToBuffer('0000777\0', 100, 8);
49
107
  // UID and GID (octal) and null-terminated
@@ -60,11 +118,11 @@ function createHeader(path, size) {
60
118
  writeToBuffer('0', 156, 1);
61
119
  // USTAR magic and version
62
120
  writeToBuffer('ustar\0\0', 257, 8);
121
+ // UStar prefix field (offset 345, 155 bytes) — used when path > 100 but fits split
122
+ if (prefix) writeToBuffer(prefix.slice(0, 155).padEnd(155, '\0'), 345, 155);
63
123
  // Calculate checksum
64
124
  let checksum = 0;
65
- for (let i = 0; i < 512; i++) {
66
- checksum += header[i];
67
- }
125
+ for (let i = 0; i < 512; i++) checksum += header[i];
68
126
  writeToBuffer(checksum.toString(8).padStart(6, '0') + '\0 ', 148, 8);
69
127
  return header;
70
128
  }
@@ -5,10 +5,19 @@ export class TarStream {
5
5
  this.currentFileSize = 0;
6
6
  }
7
7
  beginFile(path, size) {
8
- if (path.length > 100) {
9
- throw new Error(`File name too long: ${path}`);
8
+ const {
9
+ name,
10
+ prefix,
11
+ longLink
12
+ } = splitPath(path);
13
+ if (longLink) {
14
+ const pathData = Buffer.from(path + '\0');
15
+ this.output.write(createLongLinkHeader(pathData.length));
16
+ this.output.write(pathData);
17
+ const padding = pathData.length % 512 === 0 ? 0 : 512 - pathData.length % 512;
18
+ if (padding > 0) this.output.write(Buffer.alloc(padding, 0));
10
19
  }
11
- const header = createHeader(path, size);
20
+ const header = createHeader(name, prefix, size);
12
21
  this.output.write(header);
13
22
  this.currentFileSize = 0;
14
23
  }
@@ -39,11 +48,53 @@ export class TarStream {
39
48
  });
40
49
  }
41
50
  }
42
- function createHeader(path, size) {
51
+ function splitPath(path) {
52
+ if (path.length <= 100) return {
53
+ name: path,
54
+ prefix: '',
55
+ longLink: false
56
+ };
57
+ for (let i = path.length - 1; i >= 0; i--) {
58
+ if (path[i] === '/') {
59
+ const name = path.substring(i + 1);
60
+ const prefix = path.substring(0, i);
61
+ if (name.length <= 100 && prefix.length <= 155) return {
62
+ name,
63
+ prefix,
64
+ longLink: false
65
+ };
66
+ }
67
+ }
68
+ // Filename itself is > 100 chars or path > 255 chars — use GNU LongLink
69
+ const lastSlash = path.lastIndexOf('/');
70
+ const truncatedName = (lastSlash >= 0 ? path.substring(lastSlash + 1) : path).slice(0, 100);
71
+ return {
72
+ name: truncatedName,
73
+ prefix: '',
74
+ longLink: true
75
+ };
76
+ }
77
+ function createLongLinkHeader(size) {
78
+ const header = Buffer.alloc(512, 0);
79
+ header.write('././@LongLink', 0, 100);
80
+ header.write('0000644\0', 100, 8);
81
+ header.write('0000000\0', 108, 8);
82
+ header.write('0000000\0', 116, 8);
83
+ header.write(size.toString(8).padStart(11, '0') + '\0', 124, 12);
84
+ header.write('00000000000\0', 136, 12);
85
+ header.write(' ', 148, 8);
86
+ header.write('L', 156, 1);
87
+ header.write('ustar\0\0', 257, 8);
88
+ let checksum = 0;
89
+ for (let i = 0; i < 512; i++) checksum += header[i];
90
+ header.write(checksum.toString(8).padStart(6, '0') + '\0 ', 148, 8);
91
+ return header;
92
+ }
93
+ function createHeader(name, prefix, size) {
43
94
  // Initialize header with zeros
44
95
  const header = Buffer.alloc(512, 0);
45
96
  // File name, truncated to 100 characters if necessary
46
- header.write(path.slice(0, 100).padEnd(100, '\0'), 0, 100);
97
+ header.write(name.slice(0, 100).padEnd(100, '\0'), 0, 100);
47
98
  // File mode (octal) and null-terminated
48
99
  header.write('0000777\0', 100, 8);
49
100
  // UID and GID (octal) and null-terminated
@@ -60,11 +111,11 @@ function createHeader(path, size) {
60
111
  header.write('0', 156, 1);
61
112
  // USTAR magic and version
62
113
  header.write('ustar\0\0', 257, 8);
114
+ // UStar prefix field (offset 345, 155 bytes) — used when path > 100 but fits split
115
+ if (prefix) header.write(prefix.slice(0, 155).padEnd(155, '\0'), 345, 155);
63
116
  // Calculate checksum
64
117
  let checksum = 0;
65
- for (let i = 0; i < 512; i++) {
66
- checksum += header[i];
67
- }
118
+ for (let i = 0; i < 512; i++) checksum += header[i];
68
119
  header.write(checksum.toString(8).padStart(6, '0') + '\0 ', 148, 8);
69
120
  return header;
70
121
  }
@@ -9,6 +9,9 @@ export class BZZ {
9
9
  static fromPLUR(plur) {
10
10
  return new BZZ(new FixedPointNumber(plur, BZZ.DIGITS));
11
11
  }
12
+ static fromFloat(float) {
13
+ return new BZZ(FixedPointNumber.fromFloat(float, BZZ.DIGITS));
14
+ }
12
15
  toPLURString() {
13
16
  return this.state.toString();
14
17
  }
@@ -18,6 +21,9 @@ export class BZZ {
18
21
  toDecimalString() {
19
22
  return this.state.toDecimalString();
20
23
  }
24
+ toFloat() {
25
+ return this.state.toFloat();
26
+ }
21
27
  toSignificantDigits(digits) {
22
28
  return this.toDecimalString().slice(0, this.toDecimalString().indexOf('.') + digits + 1);
23
29
  }
@@ -78,6 +84,9 @@ export class DAI {
78
84
  static fromWei(wei) {
79
85
  return new DAI(new FixedPointNumber(wei, DAI.DIGITS));
80
86
  }
87
+ static fromFloat(float) {
88
+ return new DAI(FixedPointNumber.fromFloat(float, DAI.DIGITS));
89
+ }
81
90
  toWeiString() {
82
91
  return this.state.toString();
83
92
  }
@@ -90,6 +99,9 @@ export class DAI {
90
99
  toSignificantDigits(digits) {
91
100
  return this.toDecimalString().slice(0, this.toDecimalString().indexOf('.') + digits + 1);
92
101
  }
102
+ toFloat() {
103
+ return this.state.toFloat();
104
+ }
93
105
  /**
94
106
  * Does not mutate the current DAI instance.
95
107
  *
@@ -1157,12 +1157,12 @@ export declare class Bee {
1157
1157
  /**
1158
1158
  * Calculates the `amount` and expected duration extension for topping up a postage batch with a given BZZ value.
1159
1159
  *
1160
- * @param postageBatchId
1160
+ * @param depth Depth of the postage batch to top up.
1161
1161
  * @param bzz The amount of BZZ to spend on the top-up.
1162
1162
  * @param requestOptions Options for making requests, such as timeouts, custom HTTP agents, headers, etc.
1163
1163
  * @returns An object with `amount` (to pass to {@link topUpBatch}) and `duration` (the expected TTL extension).
1164
1164
  */
1165
- calculateTopUpForBzz(postageBatchId: BatchId | Uint8Array | string, bzz: BZZ, requestOptions?: BeeRequestOptions): Promise<{
1165
+ calculateTopUpForBzz(depth: number, bzz: BZZ, requestOptions?: BeeRequestOptions): Promise<{
1166
1166
  amount: bigint;
1167
1167
  duration: Duration;
1168
1168
  }>;
@@ -5,9 +5,11 @@ export declare class BZZ {
5
5
  private constructor();
6
6
  static fromDecimalString(string: string): BZZ;
7
7
  static fromPLUR(plur: NumberString | string | bigint): BZZ;
8
+ static fromFloat(float: number): BZZ;
8
9
  toPLURString(): string;
9
10
  toPLURBigInt(): bigint;
10
11
  toDecimalString(): string;
12
+ toFloat(): number;
11
13
  toSignificantDigits(digits: number): string;
12
14
  /**
13
15
  * Does not mutate the current BZZ instance.
@@ -43,10 +45,12 @@ export declare class DAI {
43
45
  private constructor();
44
46
  static fromDecimalString(string: string): DAI;
45
47
  static fromWei(wei: NumberString | string | bigint): DAI;
48
+ static fromFloat(float: number): DAI;
46
49
  toWeiString(): string;
47
50
  toWeiBigInt(): bigint;
48
51
  toDecimalString(): string;
49
52
  toSignificantDigits(digits: number): string;
53
+ toFloat(): number;
50
54
  /**
51
55
  * Does not mutate the current DAI instance.
52
56
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ethersphere/bee-js",
3
- "version": "12.0.0",
3
+ "version": "12.2.0",
4
4
  "description": "Javascript client for Bee",
5
5
  "keywords": [
6
6
  "bee",
@@ -44,7 +44,9 @@
44
44
  "./dist/cjs/utils/chunk-stream.js": "./dist/cjs/utils/chunk-stream.browser.js",
45
45
  "./dist/mjs/utils/chunk-stream.js": "./dist/mjs/utils/chunk-stream.browser.js",
46
46
  "./dist/cjs/utils/collection.node.js": "./dist/cjs/utils/collection.browser.js",
47
- "./dist/mjs/utils/collection.node.js": "./dist/mjs/utils/collection.browser.js"
47
+ "./dist/mjs/utils/collection.node.js": "./dist/mjs/utils/collection.browser.js",
48
+ "./dist/cjs/utils/tar.js": "./dist/cjs/utils/tar.browser.js",
49
+ "./dist/mjs/utils/tar.js": "./dist/mjs/utils/tar.browser.js"
48
50
  },
49
51
  "files": [
50
52
  "dist"
@@ -56,13 +58,14 @@
56
58
  "build:types": "tsc --emitDeclarationOnly --declaration --outDir dist/types",
57
59
  "build:browser": "webpack --progress",
58
60
  "test": "TS_NODE_PROJECT=tsconfig.test.json jest --runInBand --verbose --forceExit",
61
+ "test:browser": "TS_NODE_PROJECT=tsconfig.test.json jest --config jest.browser.config.js --runInBand --verbose --forceExit",
59
62
  "check": "tsc --project tsconfig.test.json",
60
63
  "lint": "eslint \"src/**/*.ts\" \"test/**/*.ts\" && prettier --check \"src/**/*.ts\" \"test/**/*.ts\"",
61
64
  "depcheck": "depcheck ."
62
65
  },
63
66
  "dependencies": {
64
67
  "axios": "^1.15.1",
65
- "cafe-utility": "^33.6.1",
68
+ "cafe-utility": "^33.9.0",
66
69
  "debug": "^4.4.1",
67
70
  "isomorphic-ws": "^4.0.1",
68
71
  "semver": "^7.3.5",
@@ -93,6 +96,7 @@
93
96
  "eslint-plugin-unused-imports": "^2.0.0",
94
97
  "husky": "^8.0.1",
95
98
  "jest": "^30.2.0",
99
+ "jest-environment-jsdom": "^30.4.1",
96
100
  "prettier": "^2.6.2",
97
101
  "rimraf": "^3.0.2",
98
102
  "terser-webpack-plugin": "^5.3.1",