@ethersphere/bee-js 8.3.1 → 9.0.2
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/README.md +192 -50
- package/dist/cjs/bee-dev.js +78 -0
- package/dist/cjs/bee.js +341 -417
- package/dist/cjs/chunk/bmt.js +15 -32
- package/dist/cjs/chunk/cac.js +26 -36
- package/dist/cjs/chunk/soc.js +56 -51
- package/dist/cjs/feed/identifier.js +3 -28
- package/dist/cjs/feed/index.js +95 -44
- package/dist/cjs/feed/retrievable.js +11 -22
- package/dist/cjs/index.js +17 -1
- package/dist/cjs/manifest/manifest.js +369 -0
- package/dist/cjs/modules/bytes.js +24 -12
- package/dist/cjs/modules/bzz.js +24 -34
- package/dist/cjs/modules/chunk.js +13 -7
- package/dist/cjs/modules/debug/balance.js +29 -4
- package/dist/cjs/modules/debug/chequebook.js +60 -16
- package/dist/cjs/modules/debug/connectivity.js +82 -4
- package/dist/cjs/modules/debug/settlements.js +22 -2
- package/dist/cjs/modules/debug/stake.js +29 -11
- package/dist/cjs/modules/debug/stamps.js +88 -7
- package/dist/cjs/modules/debug/states.js +25 -3
- package/dist/cjs/modules/debug/status.js +45 -47
- package/dist/cjs/modules/debug/transactions.js +27 -5
- package/dist/cjs/modules/envelope.js +8 -6
- package/dist/cjs/modules/feed.js +25 -10
- package/dist/cjs/modules/grantee.js +18 -12
- package/dist/cjs/modules/gsoc.js +24 -0
- package/dist/cjs/modules/pinning.js +13 -2
- package/dist/cjs/modules/pss.js +9 -3
- package/dist/cjs/modules/soc.js +9 -4
- package/dist/cjs/modules/stewardship.js +7 -3
- package/dist/cjs/modules/tag.js +35 -3
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/stamper/stamper.js +43 -0
- package/dist/cjs/types/debug.js +16 -1
- package/dist/cjs/types/index.js +2 -24
- package/dist/cjs/utils/bytes.js +67 -115
- package/dist/cjs/utils/chunk-size.js +17 -0
- package/dist/cjs/utils/chunk-stream.browser.js +85 -0
- package/dist/cjs/utils/chunk-stream.js +84 -0
- package/dist/cjs/utils/cid.js +5 -6
- package/dist/cjs/utils/collection.browser.js +2 -2
- package/dist/cjs/utils/collection.js +3 -2
- package/dist/cjs/utils/collection.node.js +0 -2
- package/dist/cjs/utils/constants.js +7 -3
- package/dist/cjs/utils/data.browser.js +6 -3
- package/dist/cjs/utils/data.js +8 -4
- package/dist/cjs/utils/duration.js +51 -0
- package/dist/cjs/utils/expose.js +11 -40
- package/dist/cjs/utils/headers.js +79 -52
- package/dist/cjs/utils/http.js +34 -10
- package/dist/cjs/utils/mime.js +78 -0
- package/dist/cjs/utils/pss.js +3 -4
- package/dist/cjs/utils/redundancy.js +18 -14
- package/dist/cjs/utils/resource-locator.js +17 -0
- package/dist/cjs/utils/size.js +35 -0
- package/dist/cjs/utils/stamps.js +67 -51
- package/dist/cjs/utils/tar-uploader.browser.js +2 -2
- package/dist/cjs/utils/tar-uploader.js +2 -2
- package/dist/cjs/utils/tokens.js +144 -0
- package/dist/cjs/utils/type.js +142 -350
- package/dist/cjs/utils/typed-bytes.js +179 -0
- package/dist/cjs/utils/upload-progress.js +2 -0
- package/dist/cjs/utils/url.js +0 -4
- package/dist/cjs/utils/workaround.js +27 -0
- package/dist/index.browser.min.js +1 -2
- package/dist/index.browser.min.js.map +1 -1
- package/dist/mjs/bee-dev.js +98 -0
- package/dist/mjs/bee.js +367 -411
- package/dist/mjs/chunk/bmt.js +13 -29
- package/dist/mjs/chunk/cac.js +26 -34
- package/dist/mjs/chunk/soc.js +57 -53
- package/dist/mjs/feed/identifier.js +3 -26
- package/dist/mjs/feed/index.js +98 -51
- package/dist/mjs/feed/retrievable.js +12 -23
- package/dist/mjs/index.js +10 -1
- package/dist/mjs/manifest/manifest.js +371 -0
- package/dist/mjs/modules/bytes.js +27 -15
- package/dist/mjs/modules/bzz.js +25 -32
- package/dist/mjs/modules/chunk.js +16 -8
- package/dist/mjs/modules/debug/balance.js +61 -4
- package/dist/mjs/modules/debug/chequebook.js +116 -16
- package/dist/mjs/modules/debug/connectivity.js +144 -3
- package/dist/mjs/modules/debug/settlements.js +46 -2
- package/dist/mjs/modules/debug/stake.js +69 -11
- package/dist/mjs/modules/debug/stamps.js +184 -7
- package/dist/mjs/modules/debug/states.js +55 -3
- package/dist/mjs/modules/debug/status.js +97 -45
- package/dist/mjs/modules/debug/transactions.js +61 -5
- package/dist/mjs/modules/envelope.js +11 -9
- package/dist/mjs/modules/feed.js +26 -10
- package/dist/mjs/modules/grantee.js +35 -13
- package/dist/mjs/modules/gsoc.js +16 -0
- package/dist/mjs/modules/pinning.js +23 -2
- package/dist/mjs/modules/pss.js +10 -4
- package/dist/mjs/modules/soc.js +10 -5
- package/dist/mjs/modules/stewardship.js +14 -4
- package/dist/mjs/modules/tag.js +93 -3
- package/dist/mjs/package.json +2 -1
- package/dist/mjs/stamper/stamper.js +39 -0
- package/dist/mjs/types/debug.js +15 -1
- package/dist/mjs/types/index.js +2 -24
- package/dist/mjs/utils/bytes.js +63 -104
- package/dist/mjs/utils/chunk-size.js +13 -0
- package/dist/mjs/utils/chunk-stream.browser.js +85 -0
- package/dist/mjs/utils/chunk-stream.js +87 -0
- package/dist/mjs/utils/cid.js +5 -6
- package/dist/mjs/utils/collection.browser.js +2 -2
- package/dist/mjs/utils/collection.js +2 -2
- package/dist/mjs/utils/collection.node.js +0 -2
- package/dist/mjs/utils/constants.js +6 -2
- package/dist/mjs/utils/data.browser.js +9 -3
- package/dist/mjs/utils/data.js +12 -4
- package/dist/mjs/utils/duration.js +47 -0
- package/dist/mjs/utils/expose.js +2 -7
- package/dist/mjs/utils/headers.js +73 -48
- package/dist/mjs/utils/http.js +33 -11
- package/dist/mjs/utils/mime.js +75 -0
- package/dist/mjs/utils/pss.js +3 -4
- package/dist/mjs/utils/redundancy.js +18 -8
- package/dist/mjs/utils/resource-locator.js +13 -0
- package/dist/mjs/utils/size.js +31 -0
- package/dist/mjs/utils/stamps.js +47 -44
- package/dist/mjs/utils/tar-uploader.browser.js +2 -2
- package/dist/mjs/utils/tar-uploader.js +2 -2
- package/dist/mjs/utils/tokens.js +139 -0
- package/dist/mjs/utils/type.js +216 -310
- package/dist/mjs/utils/typed-bytes.js +160 -0
- package/dist/mjs/utils/upload-progress.js +1 -0
- package/dist/mjs/utils/url.js +0 -4
- package/dist/mjs/utils/workaround.js +22 -0
- package/dist/types/bee-dev.d.ts +5 -0
- package/dist/types/bee.d.ts +88 -165
- package/dist/types/chunk/bmt.d.ts +2 -2
- package/dist/types/chunk/cac.d.ts +7 -24
- package/dist/types/chunk/soc.d.ts +15 -15
- package/dist/types/feed/identifier.d.ts +2 -4
- package/dist/types/feed/index.d.ts +14 -18
- package/dist/types/feed/retrievable.d.ts +3 -4
- package/dist/types/index.d.ts +28 -1
- package/dist/types/manifest/manifest.d.ts +106 -0
- package/dist/types/modules/bytes.d.ts +8 -5
- package/dist/types/modules/bzz.d.ts +8 -10
- package/dist/types/modules/chunk.d.ts +4 -3
- package/dist/types/modules/debug/balance.d.ts +3 -2
- package/dist/types/modules/debug/chequebook.d.ts +7 -6
- package/dist/types/modules/debug/connectivity.d.ts +5 -3
- package/dist/types/modules/debug/settlements.d.ts +2 -1
- package/dist/types/modules/debug/stake.d.ts +4 -2
- package/dist/types/modules/debug/stamps.d.ts +5 -4
- package/dist/types/modules/debug/status.d.ts +6 -25
- package/dist/types/modules/debug/transactions.d.ts +5 -4
- package/dist/types/modules/envelope.d.ts +3 -2
- package/dist/types/modules/feed.d.ts +20 -16
- package/dist/types/modules/grantee.d.ts +7 -6
- package/dist/types/modules/gsoc.d.ts +7 -0
- package/dist/types/modules/pinning.d.ts +2 -4
- package/dist/types/modules/pss.d.ts +4 -3
- package/dist/types/modules/soc.d.ts +3 -2
- package/dist/types/modules/stewardship.d.ts +4 -4
- package/dist/types/modules/tag.d.ts +2 -1
- package/dist/types/stamper/stamper.d.ts +15 -0
- package/dist/types/types/debug.d.ts +63 -115
- package/dist/types/types/index.d.ts +103 -204
- package/dist/types/utils/bytes.d.ts +16 -90
- package/dist/types/utils/chunk-size.d.ts +1 -0
- package/dist/types/utils/chunk-stream.browser.d.ts +6 -0
- package/dist/types/utils/chunk-stream.d.ts +6 -0
- package/dist/types/utils/cid.d.ts +3 -2
- package/dist/types/utils/collection.browser.d.ts +2 -2
- package/dist/types/utils/collection.d.ts +2 -1
- package/dist/types/utils/collection.node.d.ts +0 -1
- package/dist/types/utils/constants.d.ts +4 -1
- package/dist/types/utils/duration.d.ts +17 -0
- package/dist/types/utils/error.d.ts +2 -2
- package/dist/types/utils/expose.d.ts +2 -7
- package/dist/types/utils/headers.d.ts +3 -4
- package/dist/types/utils/mime.d.ts +1 -0
- package/dist/types/utils/pss.d.ts +2 -2
- package/dist/types/utils/resource-locator.d.ts +6 -0
- package/dist/types/utils/size.d.ts +16 -0
- package/dist/types/utils/stamps.d.ts +27 -33
- package/dist/types/utils/tar-uploader.browser.d.ts +3 -4
- package/dist/types/utils/tar-uploader.d.ts +3 -4
- package/dist/types/utils/tokens.d.ts +77 -0
- package/dist/types/utils/type.d.ts +20 -52
- package/dist/types/utils/typed-bytes.d.ts +68 -0
- package/dist/types/utils/upload-progress.d.ts +4 -0
- package/dist/types/utils/workaround.d.ts +2 -0
- package/package.json +11 -17
- package/dist/cjs/chunk/signer.js +0 -126
- package/dist/cjs/chunk/span.js +0 -25
- package/dist/cjs/feed/json.js +0 -28
- package/dist/cjs/feed/topic.js +0 -25
- package/dist/cjs/feed/type.js +0 -15
- package/dist/cjs/modules/debug/chunk.js +0 -21
- package/dist/cjs/modules/debug/tag.js +0 -19
- package/dist/cjs/utils/eth.js +0 -216
- package/dist/cjs/utils/hash.js +0 -21
- package/dist/cjs/utils/hex.js +0 -150
- package/dist/cjs/utils/reference.js +0 -36
- package/dist/index.browser.min.js.LICENSE.txt +0 -8
- package/dist/mjs/chunk/signer.js +0 -114
- package/dist/mjs/chunk/span.js +0 -21
- package/dist/mjs/feed/json.js +0 -26
- package/dist/mjs/feed/topic.js +0 -19
- package/dist/mjs/feed/type.js +0 -10
- package/dist/mjs/modules/debug/chunk.js +0 -17
- package/dist/mjs/modules/debug/tag.js +0 -15
- package/dist/mjs/utils/eth.js +0 -192
- package/dist/mjs/utils/hash.js +0 -16
- package/dist/mjs/utils/hex.js +0 -135
- package/dist/mjs/utils/reference.js +0 -29
- package/dist/types/chunk/signer.d.ts +0 -31
- package/dist/types/chunk/span.d.ts +0 -10
- package/dist/types/feed/json.d.ts +0 -4
- package/dist/types/feed/topic.d.ts +0 -3
- package/dist/types/feed/type.d.ts +0 -6
- package/dist/types/modules/debug/chunk.d.ts +0 -10
- package/dist/types/modules/debug/tag.d.ts +0 -8
- package/dist/types/utils/eth.d.ts +0 -67
- package/dist/types/utils/hash.d.ts +0 -9
- package/dist/types/utils/hex.d.ts +0 -86
- package/dist/types/utils/reference.d.ts +0 -2
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
import { Binary, MerkleTree, Optional, Uint8ArrayReader } from 'cafe-utility';
|
|
2
|
+
import { NULL_ADDRESS } from "../index.js";
|
|
3
|
+
import { Reference } from "../utils/typed-bytes.js";
|
|
4
|
+
const ENCODER = new TextEncoder();
|
|
5
|
+
const DECODER = new TextDecoder();
|
|
6
|
+
const TYPE_VALUE = 2;
|
|
7
|
+
const TYPE_EDGE = 4;
|
|
8
|
+
const TYPE_WITH_PATH_SEPARATOR = 8;
|
|
9
|
+
const TYPE_WITH_METADATA = 16;
|
|
10
|
+
const PATH_SEPARATOR = new Uint8Array([47]);
|
|
11
|
+
const VERSION_02_HASH_HEX = '5768b3b6a7db56d21d1abff40d41cebfc83448fed8d7e9b06ec0d3b073f28f7b';
|
|
12
|
+
const VERSION_02_HASH = Binary.hexToUint8Array(VERSION_02_HASH_HEX);
|
|
13
|
+
export class Fork {
|
|
14
|
+
constructor(prefix, node) {
|
|
15
|
+
this.prefix = prefix;
|
|
16
|
+
this.node = node;
|
|
17
|
+
}
|
|
18
|
+
static split(a, b) {
|
|
19
|
+
const commonPart = Binary.commonPrefix(a.prefix, b.prefix);
|
|
20
|
+
const node = new MantarayNode({
|
|
21
|
+
path: commonPart
|
|
22
|
+
});
|
|
23
|
+
const newAFork = new Fork(a.prefix.slice(commonPart.length), a.node);
|
|
24
|
+
const newBFork = new Fork(b.prefix.slice(commonPart.length), b.node);
|
|
25
|
+
a.node.path = a.prefix.slice(commonPart.length);
|
|
26
|
+
b.node.path = b.prefix.slice(commonPart.length);
|
|
27
|
+
a.prefix = a.prefix.slice(commonPart.length);
|
|
28
|
+
b.prefix = b.prefix.slice(commonPart.length);
|
|
29
|
+
node.forks.set(newAFork.prefix[0], newAFork);
|
|
30
|
+
node.forks.set(newBFork.prefix[0], newBFork);
|
|
31
|
+
newAFork.node.parent = node;
|
|
32
|
+
newBFork.node.parent = node;
|
|
33
|
+
return new Fork(commonPart, node);
|
|
34
|
+
}
|
|
35
|
+
marshal() {
|
|
36
|
+
if (!this.node.selfAddress) {
|
|
37
|
+
throw Error('Fork#marshal node.selfAddress is not set');
|
|
38
|
+
}
|
|
39
|
+
const data = [];
|
|
40
|
+
data.push(new Uint8Array([this.node.determineType()]));
|
|
41
|
+
data.push(Binary.numberToUint8(this.prefix.length));
|
|
42
|
+
data.push(this.prefix);
|
|
43
|
+
if (this.prefix.length < 30) {
|
|
44
|
+
data.push(new Uint8Array(30 - this.prefix.length));
|
|
45
|
+
}
|
|
46
|
+
data.push(this.node.selfAddress);
|
|
47
|
+
if (this.node.metadata) {
|
|
48
|
+
const metadataBytes = Binary.padEndToMultiple(new Uint8Array([0x00, 0x00, ...ENCODER.encode(JSON.stringify(this.node.metadata))]), 32, 0x0a);
|
|
49
|
+
const metadataLengthBytes = Binary.numberToUint16(metadataBytes.length - 2, 'BE');
|
|
50
|
+
metadataBytes.set(metadataLengthBytes, 0);
|
|
51
|
+
data.push(metadataBytes);
|
|
52
|
+
}
|
|
53
|
+
return Binary.concatBytes(...data);
|
|
54
|
+
}
|
|
55
|
+
static unmarshal(reader) {
|
|
56
|
+
const type = Binary.uint8ToNumber(reader.read(1));
|
|
57
|
+
const prefixLength = Binary.uint8ToNumber(reader.read(1));
|
|
58
|
+
const prefix = reader.read(prefixLength);
|
|
59
|
+
reader.read(30 - prefixLength);
|
|
60
|
+
const targetAddress = reader.read(32);
|
|
61
|
+
let metadata = undefined;
|
|
62
|
+
if (isType(type, TYPE_WITH_METADATA)) {
|
|
63
|
+
const metadataLength = Binary.uint16ToNumber(reader.read(2), 'BE');
|
|
64
|
+
metadata = JSON.parse(DECODER.decode(reader.read(metadataLength)));
|
|
65
|
+
}
|
|
66
|
+
return new Fork(prefix, new MantarayNode({
|
|
67
|
+
targetAddress,
|
|
68
|
+
metadata,
|
|
69
|
+
path: prefix
|
|
70
|
+
}));
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
export class MantarayNode {
|
|
74
|
+
constructor(options) {
|
|
75
|
+
this.obfuscationKey = new Uint8Array(32);
|
|
76
|
+
this.selfAddress = null;
|
|
77
|
+
this.targetAddress = new Uint8Array(32);
|
|
78
|
+
this.metadata = null;
|
|
79
|
+
this.path = new Uint8Array(0);
|
|
80
|
+
this.forks = new Map();
|
|
81
|
+
this.parent = null;
|
|
82
|
+
if (options?.targetAddress) {
|
|
83
|
+
this.targetAddress = options.targetAddress;
|
|
84
|
+
}
|
|
85
|
+
if (options?.selfAddress) {
|
|
86
|
+
this.selfAddress = options.selfAddress;
|
|
87
|
+
}
|
|
88
|
+
if (options?.metadata) {
|
|
89
|
+
this.metadata = options.metadata;
|
|
90
|
+
}
|
|
91
|
+
if (options?.obfuscationKey) {
|
|
92
|
+
this.obfuscationKey = options.obfuscationKey;
|
|
93
|
+
}
|
|
94
|
+
if (options?.path) {
|
|
95
|
+
this.path = options.path;
|
|
96
|
+
}
|
|
97
|
+
if (options?.parent) {
|
|
98
|
+
this.parent = options.parent;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
get fullPath() {
|
|
102
|
+
return Binary.concatBytes(this.parent?.fullPath ?? new Uint8Array(0), this.path);
|
|
103
|
+
}
|
|
104
|
+
get fullPathString() {
|
|
105
|
+
return DECODER.decode(this.fullPath);
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Returns the metadata at the `/` path to access idiomatic properties.
|
|
109
|
+
*/
|
|
110
|
+
getRootMetadata() {
|
|
111
|
+
const node = this.find('/');
|
|
112
|
+
if (node && node.metadata) {
|
|
113
|
+
return Optional.of(node.metadata);
|
|
114
|
+
}
|
|
115
|
+
return Optional.empty();
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Returns the `swarm-index-document` and `swarm-error-document` metadata values.
|
|
119
|
+
*/
|
|
120
|
+
getDocsMetadata() {
|
|
121
|
+
const node = this.find('/');
|
|
122
|
+
if (!node || !node.metadata) {
|
|
123
|
+
return {
|
|
124
|
+
indexDocument: null,
|
|
125
|
+
errorDocument: null
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
return {
|
|
129
|
+
indexDocument: node.metadata['website-index-document'] ?? null,
|
|
130
|
+
errorDocument: node.metadata['website-error-document'] ?? null
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Attempts to resolve the manifest as a feed, returning the latest update.
|
|
135
|
+
*/
|
|
136
|
+
async resolveFeed(bee, requestOptions) {
|
|
137
|
+
const node = this.find('/');
|
|
138
|
+
if (!node || !node.metadata) {
|
|
139
|
+
return Optional.empty();
|
|
140
|
+
}
|
|
141
|
+
const owner = node.metadata['swarm-feed-owner'];
|
|
142
|
+
const topic = node.metadata['swarm-feed-topic'];
|
|
143
|
+
if (!owner || !topic) {
|
|
144
|
+
return Optional.empty();
|
|
145
|
+
}
|
|
146
|
+
return Optional.of(await bee.fetchLatestFeedUpdate(topic, owner, requestOptions));
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Gets the binary representation of the node.
|
|
150
|
+
*/
|
|
151
|
+
async marshal() {
|
|
152
|
+
for (const fork of this.forks.values()) {
|
|
153
|
+
if (!fork.node.selfAddress) {
|
|
154
|
+
fork.node.selfAddress = (await fork.node.calculateSelfAddress()).toUint8Array();
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
const header = new Uint8Array(32);
|
|
158
|
+
header.set(VERSION_02_HASH, 0);
|
|
159
|
+
header.set(Binary.equals(this.targetAddress, NULL_ADDRESS) && Binary.equals(this.path, new Uint8Array([47])) ? Binary.numberToUint8(0) : Binary.numberToUint8(this.targetAddress.length), 31);
|
|
160
|
+
const forkBitmap = new Uint8Array(32);
|
|
161
|
+
for (const fork of this.forks.keys()) {
|
|
162
|
+
Binary.setBit(forkBitmap, fork, 1, 'LE');
|
|
163
|
+
}
|
|
164
|
+
const forks = [];
|
|
165
|
+
for (let i = 0; i < 256; i++) {
|
|
166
|
+
if (Binary.getBit(forkBitmap, i, 'LE')) {
|
|
167
|
+
forks.push(this.forks.get(i).marshal());
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
const data = Binary.xorCypher(Binary.concatBytes(header, Binary.equals(this.targetAddress, NULL_ADDRESS) && Binary.equals(this.path, new Uint8Array([47])) ? new Uint8Array(0) : this.targetAddress, forkBitmap, ...forks), this.obfuscationKey);
|
|
171
|
+
return Binary.concatBytes(this.obfuscationKey, data);
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Downloads and unmarshals a MantarayNode from the given reference.
|
|
175
|
+
*
|
|
176
|
+
* Do not forget calling `loadRecursively` on the returned node to load the entire tree.
|
|
177
|
+
*/
|
|
178
|
+
static async unmarshal(bee, reference, options, requestOptions) {
|
|
179
|
+
const data = (await bee.downloadData(reference, options, requestOptions)).toUint8Array();
|
|
180
|
+
return this.unmarshalFromData(data);
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Unmarshals a MantarayNode from the given data.
|
|
184
|
+
*
|
|
185
|
+
* Do not forget calling `loadRecursively` on the returned node to load the entire tree.
|
|
186
|
+
*/
|
|
187
|
+
static unmarshalFromData(data) {
|
|
188
|
+
const obfuscationKey = data.subarray(0, 32);
|
|
189
|
+
const decrypted = Binary.xorCypher(data.subarray(32), obfuscationKey);
|
|
190
|
+
const reader = new Uint8ArrayReader(decrypted);
|
|
191
|
+
const versionHash = reader.read(31);
|
|
192
|
+
if (!Binary.equals(versionHash, VERSION_02_HASH.slice(0, 31))) {
|
|
193
|
+
throw new Error('MantarayNode#unmarshal invalid version hash');
|
|
194
|
+
}
|
|
195
|
+
const targetAddressLength = Binary.uint8ToNumber(reader.read(1));
|
|
196
|
+
const targetAddress = targetAddressLength === 0 ? NULL_ADDRESS : reader.read(targetAddressLength);
|
|
197
|
+
const node = new MantarayNode({
|
|
198
|
+
targetAddress,
|
|
199
|
+
obfuscationKey
|
|
200
|
+
});
|
|
201
|
+
const forkBitmap = reader.read(32);
|
|
202
|
+
for (let i = 0; i < 256; i++) {
|
|
203
|
+
if (Binary.getBit(forkBitmap, i, 'LE')) {
|
|
204
|
+
const newFork = Fork.unmarshal(reader);
|
|
205
|
+
node.forks.set(i, newFork);
|
|
206
|
+
newFork.node.parent = node;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return node;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Adds a fork to the node.
|
|
213
|
+
*/
|
|
214
|
+
addFork(path, reference, metadata) {
|
|
215
|
+
this.selfAddress = null;
|
|
216
|
+
path = path instanceof Uint8Array ? path : ENCODER.encode(path);
|
|
217
|
+
// TODO: this should not be ignored
|
|
218
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
219
|
+
let tip = this;
|
|
220
|
+
while (path.length) {
|
|
221
|
+
const prefix = path.slice(0, 30);
|
|
222
|
+
path = path.slice(30);
|
|
223
|
+
const isLast = path.length === 0;
|
|
224
|
+
const [bestMatch, matchedPath] = tip.findClosest(prefix);
|
|
225
|
+
const remainingPath = prefix.slice(matchedPath.length);
|
|
226
|
+
if (matchedPath.length) {
|
|
227
|
+
tip = bestMatch;
|
|
228
|
+
}
|
|
229
|
+
if (!remainingPath.length) {
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
const newFork = new Fork(remainingPath, new MantarayNode({
|
|
233
|
+
targetAddress: isLast ? new Reference(reference).toUint8Array() : undefined,
|
|
234
|
+
metadata: isLast ? metadata : undefined,
|
|
235
|
+
path: remainingPath
|
|
236
|
+
}));
|
|
237
|
+
const existing = bestMatch.forks.get(remainingPath[0]);
|
|
238
|
+
if (existing) {
|
|
239
|
+
const fork = Fork.split(newFork, existing);
|
|
240
|
+
tip.forks.set(remainingPath[0], fork);
|
|
241
|
+
fork.node.parent = tip;
|
|
242
|
+
tip.selfAddress = null;
|
|
243
|
+
tip = newFork.node;
|
|
244
|
+
} else {
|
|
245
|
+
tip.forks.set(remainingPath[0], newFork);
|
|
246
|
+
newFork.node.parent = tip;
|
|
247
|
+
tip.selfAddress = null;
|
|
248
|
+
tip = newFork.node;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Removes a fork from the node.
|
|
254
|
+
*/
|
|
255
|
+
removeFork(path) {
|
|
256
|
+
this.selfAddress = null;
|
|
257
|
+
path = path instanceof Uint8Array ? path : ENCODER.encode(path);
|
|
258
|
+
if (path.length === 0) {
|
|
259
|
+
throw Error('MantarayNode#removeFork [path] parameter cannot be empty');
|
|
260
|
+
}
|
|
261
|
+
const match = this.find(path);
|
|
262
|
+
if (!match) {
|
|
263
|
+
throw Error('MantarayNode#removeFork fork not found');
|
|
264
|
+
}
|
|
265
|
+
const [parent, matchedPath] = this.findClosest(path.slice(0, path.length - 1));
|
|
266
|
+
parent.forks.delete(path.slice(matchedPath.length)[0]);
|
|
267
|
+
for (const fork of match.forks.values()) {
|
|
268
|
+
parent.addFork(Binary.concatBytes(match.path, fork.prefix), fork.node.targetAddress, fork.node.metadata);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Calculates the self address of the node.
|
|
273
|
+
*/
|
|
274
|
+
async calculateSelfAddress() {
|
|
275
|
+
if (this.selfAddress) {
|
|
276
|
+
return new Reference(this.selfAddress);
|
|
277
|
+
}
|
|
278
|
+
return new Reference((await MerkleTree.root(await this.marshal())).hash());
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Saves the node and its children recursively.
|
|
282
|
+
*/
|
|
283
|
+
async saveRecursively(bee, postageBatchId, options, requestOptions) {
|
|
284
|
+
for (const fork of this.forks.values()) {
|
|
285
|
+
await fork.node.saveRecursively(bee, postageBatchId, options, requestOptions);
|
|
286
|
+
}
|
|
287
|
+
const result = await bee.uploadData(postageBatchId, await this.marshal(), options, requestOptions);
|
|
288
|
+
this.selfAddress = result.reference.toUint8Array();
|
|
289
|
+
return result;
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Loads the node and its children recursively.
|
|
293
|
+
*/
|
|
294
|
+
async loadRecursively(bee, options, requestOptions) {
|
|
295
|
+
for (const fork of this.forks.values()) {
|
|
296
|
+
const node = await MantarayNode.unmarshal(bee, fork.node.targetAddress, options, requestOptions);
|
|
297
|
+
fork.node.targetAddress = node.targetAddress;
|
|
298
|
+
fork.node.forks = node.forks;
|
|
299
|
+
fork.node.path = fork.prefix;
|
|
300
|
+
fork.node.parent = this;
|
|
301
|
+
await fork.node.loadRecursively(bee, options, requestOptions);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Finds a node in the tree by its path.
|
|
306
|
+
*/
|
|
307
|
+
find(path) {
|
|
308
|
+
const [closest, match] = this.findClosest(path);
|
|
309
|
+
return match.length === path.length ? closest : null;
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Finds the closest node in the tree to the given path.
|
|
313
|
+
*/
|
|
314
|
+
findClosest(path, current = new Uint8Array()) {
|
|
315
|
+
path = path instanceof Uint8Array ? path : ENCODER.encode(path);
|
|
316
|
+
if (path.length === 0) {
|
|
317
|
+
return [this, current];
|
|
318
|
+
}
|
|
319
|
+
const fork = this.forks.get(path[0]);
|
|
320
|
+
if (fork && Binary.commonPrefix(fork.prefix, path).length === fork.prefix.length) {
|
|
321
|
+
return fork.node.findClosest(path.slice(fork.prefix.length), Binary.concatBytes(current, fork.prefix));
|
|
322
|
+
}
|
|
323
|
+
return [this, current];
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Returns an array of all nodes in the tree which have a target address set.
|
|
327
|
+
*
|
|
328
|
+
* Must be called after `loadRecursively`.
|
|
329
|
+
*/
|
|
330
|
+
collect(nodes = []) {
|
|
331
|
+
for (const fork of this.forks.values()) {
|
|
332
|
+
if (!Binary.equals(fork.node.targetAddress, NULL_ADDRESS)) {
|
|
333
|
+
nodes.push(fork.node);
|
|
334
|
+
}
|
|
335
|
+
fork.node.collect(nodes);
|
|
336
|
+
}
|
|
337
|
+
return nodes;
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Returns a path:reference map of all nodes in the tree which have a target address set.
|
|
341
|
+
*
|
|
342
|
+
* Must be called after `loadRecursively`.
|
|
343
|
+
*/
|
|
344
|
+
collectAndMap() {
|
|
345
|
+
const nodes = this.collect();
|
|
346
|
+
const result = {};
|
|
347
|
+
for (const node of nodes) {
|
|
348
|
+
result[node.fullPathString] = new Reference(node.targetAddress).toHex();
|
|
349
|
+
}
|
|
350
|
+
return result;
|
|
351
|
+
}
|
|
352
|
+
determineType() {
|
|
353
|
+
let type = 0;
|
|
354
|
+
if (!Binary.equals(this.targetAddress, NULL_ADDRESS) || Binary.equals(this.path, PATH_SEPARATOR)) {
|
|
355
|
+
type |= TYPE_VALUE;
|
|
356
|
+
}
|
|
357
|
+
if (this.forks.size > 0) {
|
|
358
|
+
type |= TYPE_EDGE;
|
|
359
|
+
}
|
|
360
|
+
if (Binary.indexOf(this.path, PATH_SEPARATOR) !== -1 && !Binary.equals(this.path, PATH_SEPARATOR)) {
|
|
361
|
+
type |= TYPE_WITH_PATH_SEPARATOR;
|
|
362
|
+
}
|
|
363
|
+
if (this.metadata) {
|
|
364
|
+
type |= TYPE_WITH_METADATA;
|
|
365
|
+
}
|
|
366
|
+
return type;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
function isType(value, type) {
|
|
370
|
+
return (value & type) === type;
|
|
371
|
+
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { Optional, Types } from 'cafe-utility';
|
|
2
|
+
import { Bytes } from "../utils/bytes.js";
|
|
3
|
+
import { prepareRequestHeaders } from "../utils/headers.js";
|
|
3
4
|
import { http } from "../utils/http.js";
|
|
4
|
-
import { makeTagUid } from "../utils/type.js";
|
|
5
|
+
import { makeTagUid, prepareDownloadOptions } from "../utils/type.js";
|
|
6
|
+
import { Reference } from "../utils/typed-bytes.js";
|
|
5
7
|
const endpoint = 'bytes';
|
|
6
8
|
/**
|
|
7
9
|
* Upload data to a Bee node
|
|
@@ -19,13 +21,16 @@ export async function upload(requestOptions, data, postageBatchId, options) {
|
|
|
19
21
|
data,
|
|
20
22
|
headers: {
|
|
21
23
|
'content-type': 'application/octet-stream',
|
|
22
|
-
...
|
|
24
|
+
...prepareRequestHeaders(postageBatchId, options)
|
|
23
25
|
}
|
|
24
26
|
});
|
|
27
|
+
const body = Types.asObject(response.data, {
|
|
28
|
+
name: 'response.data'
|
|
29
|
+
});
|
|
25
30
|
return {
|
|
26
|
-
reference:
|
|
31
|
+
reference: new Reference(Types.asHexString(body.reference)),
|
|
27
32
|
tagUid: response.headers['swarm-tag'] ? makeTagUid(response.headers['swarm-tag']) : undefined,
|
|
28
|
-
historyAddress: response.headers['swarm-act-history-address']
|
|
33
|
+
historyAddress: response.headers['swarm-act-history-address'] ? Optional.of(new Reference(response.headers['swarm-act-history-address'])) : Optional.empty()
|
|
29
34
|
};
|
|
30
35
|
}
|
|
31
36
|
/**
|
|
@@ -34,9 +39,10 @@ export async function upload(requestOptions, data, postageBatchId, options) {
|
|
|
34
39
|
* @param requestOptions Options for making requests
|
|
35
40
|
* @param hash Bee content reference
|
|
36
41
|
*/
|
|
37
|
-
export async function head(requestOptions,
|
|
42
|
+
export async function head(requestOptions, reference) {
|
|
43
|
+
reference = new Reference(reference);
|
|
38
44
|
const response = await http(requestOptions, {
|
|
39
|
-
url: `${endpoint}/${
|
|
45
|
+
url: `${endpoint}/${reference}`,
|
|
40
46
|
method: 'head',
|
|
41
47
|
responseType: 'json'
|
|
42
48
|
});
|
|
@@ -50,13 +56,16 @@ export async function head(requestOptions, hash) {
|
|
|
50
56
|
* @param requestOptions Options for making requests
|
|
51
57
|
* @param hash Bee content reference
|
|
52
58
|
*/
|
|
53
|
-
export async function download(requestOptions,
|
|
59
|
+
export async function download(requestOptions, resource, options) {
|
|
60
|
+
if (options) {
|
|
61
|
+
options = prepareDownloadOptions(options);
|
|
62
|
+
}
|
|
54
63
|
const response = await http(requestOptions, {
|
|
55
64
|
responseType: 'arraybuffer',
|
|
56
|
-
url: `${endpoint}/${
|
|
57
|
-
headers:
|
|
65
|
+
url: `${endpoint}/${resource}`,
|
|
66
|
+
headers: prepareRequestHeaders(null, options)
|
|
58
67
|
});
|
|
59
|
-
return
|
|
68
|
+
return new Bytes(response.data);
|
|
60
69
|
}
|
|
61
70
|
/**
|
|
62
71
|
* Download data as a readable stream
|
|
@@ -64,11 +73,14 @@ export async function download(requestOptions, hash, options) {
|
|
|
64
73
|
* @param requestOptions Options for making requests
|
|
65
74
|
* @param hash Bee content reference
|
|
66
75
|
*/
|
|
67
|
-
export async function downloadReadable(requestOptions,
|
|
76
|
+
export async function downloadReadable(requestOptions, resource, options) {
|
|
77
|
+
if (options) {
|
|
78
|
+
options = prepareDownloadOptions(options);
|
|
79
|
+
}
|
|
68
80
|
const response = await http(requestOptions, {
|
|
69
81
|
responseType: 'stream',
|
|
70
|
-
url: `${endpoint}/${
|
|
71
|
-
headers:
|
|
82
|
+
url: `${endpoint}/${resource}`,
|
|
83
|
+
headers: prepareRequestHeaders(null, options)
|
|
72
84
|
});
|
|
73
85
|
return response.data;
|
|
74
86
|
}
|
package/dist/mjs/modules/bzz.js
CHANGED
|
@@ -1,16 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Optional, Types } from 'cafe-utility';
|
|
2
|
+
import { Bytes } from "../utils/bytes.js";
|
|
2
3
|
import { assertCollection } from "../utils/collection.js";
|
|
3
|
-
import {
|
|
4
|
+
import { prepareRequestHeaders, readFileHeaders } from "../utils/headers.js";
|
|
4
5
|
import { http } from "../utils/http.js";
|
|
5
6
|
import { uploadTar } from "../utils/tar-uploader.js";
|
|
6
7
|
import { isReadable, makeTagUid } from "../utils/type.js";
|
|
8
|
+
import { Reference } from "../utils/typed-bytes.js";
|
|
7
9
|
const bzzEndpoint = 'bzz';
|
|
8
|
-
function extractFileUploadHeaders(postageBatchId, options) {
|
|
9
|
-
const headers = extractRedundantUploadHeaders(postageBatchId, options);
|
|
10
|
-
if (options?.size) headers['content-length'] = String(options.size);
|
|
11
|
-
if (options?.contentType) headers['content-type'] = options.contentType;
|
|
12
|
-
return headers;
|
|
13
|
-
}
|
|
14
10
|
/**
|
|
15
11
|
* Upload single file
|
|
16
12
|
*
|
|
@@ -31,18 +27,19 @@ export async function uploadFile(requestOptions, data, postageBatchId, name, opt
|
|
|
31
27
|
method: 'post',
|
|
32
28
|
url: bzzEndpoint,
|
|
33
29
|
data,
|
|
34
|
-
headers:
|
|
35
|
-
...extractFileUploadHeaders(postageBatchId, options)
|
|
36
|
-
},
|
|
30
|
+
headers: prepareRequestHeaders(postageBatchId, options),
|
|
37
31
|
params: {
|
|
38
32
|
name
|
|
39
33
|
},
|
|
40
34
|
responseType: 'json'
|
|
41
35
|
});
|
|
36
|
+
const body = Types.asObject(response.data, {
|
|
37
|
+
name: 'response.data'
|
|
38
|
+
});
|
|
42
39
|
return {
|
|
43
|
-
reference:
|
|
40
|
+
reference: new Reference(Types.asHexString(body.reference)),
|
|
44
41
|
tagUid: response.headers['swarm-tag'] ? makeTagUid(response.headers['swarm-tag']) : undefined,
|
|
45
|
-
historyAddress: response.headers['swarm-act-history-address']
|
|
42
|
+
historyAddress: response.headers['swarm-act-history-address'] ? Optional.of(new Reference(response.headers['swarm-act-history-address'])) : Optional.empty()
|
|
46
43
|
};
|
|
47
44
|
}
|
|
48
45
|
/**
|
|
@@ -52,16 +49,16 @@ export async function uploadFile(requestOptions, data, postageBatchId, name, opt
|
|
|
52
49
|
* @param hash Bee file or collection hash
|
|
53
50
|
* @param path If hash is collection then this defines path to a single file in the collection
|
|
54
51
|
*/
|
|
55
|
-
export async function downloadFile(requestOptions,
|
|
52
|
+
export async function downloadFile(requestOptions, resource, path = '', options) {
|
|
56
53
|
const response = await http(requestOptions, {
|
|
57
54
|
method: 'GET',
|
|
58
55
|
responseType: 'arraybuffer',
|
|
59
|
-
url: `${bzzEndpoint}/${
|
|
60
|
-
headers:
|
|
56
|
+
url: `${bzzEndpoint}/${resource}/${path}`,
|
|
57
|
+
headers: prepareRequestHeaders(null, options)
|
|
61
58
|
});
|
|
62
59
|
const file = {
|
|
63
60
|
...readFileHeaders(response.headers),
|
|
64
|
-
data:
|
|
61
|
+
data: new Bytes(response.data)
|
|
65
62
|
};
|
|
66
63
|
return file;
|
|
67
64
|
}
|
|
@@ -72,12 +69,13 @@ export async function downloadFile(requestOptions, hash, path = '', options) {
|
|
|
72
69
|
* @param hash Bee file or collection hash
|
|
73
70
|
* @param path If hash is collection then this defines path to a single file in the collection
|
|
74
71
|
*/
|
|
75
|
-
export async function downloadFileReadable(requestOptions,
|
|
72
|
+
export async function downloadFileReadable(requestOptions, reference, path = '', options) {
|
|
73
|
+
reference = new Reference(reference);
|
|
76
74
|
const response = await http(requestOptions, {
|
|
77
75
|
method: 'GET',
|
|
78
76
|
responseType: 'stream',
|
|
79
|
-
url: `${bzzEndpoint}/${
|
|
80
|
-
headers:
|
|
77
|
+
url: `${bzzEndpoint}/${reference}/${path}`,
|
|
78
|
+
headers: prepareRequestHeaders(null, options)
|
|
81
79
|
});
|
|
82
80
|
const file = {
|
|
83
81
|
...readFileHeaders(response.headers),
|
|
@@ -85,16 +83,8 @@ export async function downloadFileReadable(requestOptions, hash, path = '', opti
|
|
|
85
83
|
};
|
|
86
84
|
return file;
|
|
87
85
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
if (options?.indexDocument) {
|
|
91
|
-
headers['swarm-index-document'] = options.indexDocument;
|
|
92
|
-
}
|
|
93
|
-
if (options?.errorDocument) {
|
|
94
|
-
headers['swarm-error-document'] = options.errorDocument;
|
|
95
|
-
}
|
|
96
|
-
return headers;
|
|
97
|
-
}
|
|
86
|
+
/*******************************************************************************************************************/
|
|
87
|
+
// Collections
|
|
98
88
|
/**
|
|
99
89
|
* Upload collection
|
|
100
90
|
* @param requestOptions Options for making requests
|
|
@@ -105,9 +95,12 @@ export function extractCollectionUploadHeaders(postageBatchId, options) {
|
|
|
105
95
|
export async function uploadCollection(requestOptions, collection, postageBatchId, options) {
|
|
106
96
|
assertCollection(collection);
|
|
107
97
|
const response = await uploadTar(requestOptions, collection, postageBatchId, options);
|
|
98
|
+
const body = Types.asObject(response.data, {
|
|
99
|
+
name: 'response.data'
|
|
100
|
+
});
|
|
108
101
|
return {
|
|
109
|
-
reference:
|
|
102
|
+
reference: new Reference(Types.asHexString(body.reference)),
|
|
110
103
|
tagUid: response.headers['swarm-tag'] ? makeTagUid(response.headers['swarm-tag']) : undefined,
|
|
111
|
-
historyAddress: response.headers['swarm-act-history-address']
|
|
104
|
+
historyAddress: response.headers['swarm-act-history-address'] ? Optional.of(new Reference(response.headers['swarm-act-history-address'])) : Optional.empty()
|
|
112
105
|
};
|
|
113
106
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { Optional, Types } from 'cafe-utility';
|
|
2
|
+
import { prepareRequestHeaders } from "../utils/headers.js";
|
|
3
3
|
import { http } from "../utils/http.js";
|
|
4
4
|
import { makeTagUid } from "../utils/type.js";
|
|
5
|
+
import { Reference } from "../utils/typed-bytes.js";
|
|
5
6
|
const endpoint = 'chunks';
|
|
6
7
|
/**
|
|
7
8
|
* Upload chunk to a Bee node
|
|
@@ -22,14 +23,19 @@ export async function upload(requestOptions, data, stamp, options) {
|
|
|
22
23
|
data,
|
|
23
24
|
headers: {
|
|
24
25
|
'content-type': 'application/octet-stream',
|
|
25
|
-
...
|
|
26
|
+
...prepareRequestHeaders(stamp, options)
|
|
26
27
|
},
|
|
27
28
|
responseType: 'json'
|
|
28
29
|
});
|
|
30
|
+
const body = Types.asObject(response.data, {
|
|
31
|
+
name: 'response.data'
|
|
32
|
+
});
|
|
29
33
|
return {
|
|
30
|
-
reference:
|
|
34
|
+
reference: new Reference(Types.asString(body.reference, {
|
|
35
|
+
name: 'reference'
|
|
36
|
+
})),
|
|
31
37
|
tagUid: response.headers['swarm-tag'] ? makeTagUid(response.headers['swarm-tag']) : undefined,
|
|
32
|
-
historyAddress: response.headers['swarm-act-history-address']
|
|
38
|
+
historyAddress: response.headers['swarm-act-history-address'] ? Optional.of(new Reference(response.headers['swarm-act-history-address'])) : Optional.empty()
|
|
33
39
|
};
|
|
34
40
|
}
|
|
35
41
|
/**
|
|
@@ -39,10 +45,12 @@ export async function upload(requestOptions, data, stamp, options) {
|
|
|
39
45
|
* @param hash Bee content reference
|
|
40
46
|
*
|
|
41
47
|
*/
|
|
42
|
-
export async function download(requestOptions,
|
|
48
|
+
export async function download(requestOptions, reference, options) {
|
|
49
|
+
reference = new Reference(reference);
|
|
43
50
|
const response = await http(requestOptions, {
|
|
44
51
|
responseType: 'arraybuffer',
|
|
45
|
-
url: `${endpoint}/${
|
|
52
|
+
url: `${endpoint}/${reference}`,
|
|
53
|
+
headers: prepareRequestHeaders(null, options)
|
|
46
54
|
});
|
|
47
|
-
return
|
|
55
|
+
return new Uint8Array(response.data);
|
|
48
56
|
}
|