smoldot 1.0.0 → 1.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/dist/cjs/index-browser.js +66 -19
- package/dist/cjs/index-deno.js +79 -56
- package/dist/cjs/index-nodejs.js +91 -40
- package/dist/cjs/instance/autogen/wasm0.js +1 -1
- package/dist/cjs/instance/autogen/wasm1.js +1 -1
- package/dist/cjs/instance/autogen/wasm2.js +1 -1
- package/dist/cjs/instance/bindings-smoldot-light.d.ts +42 -2
- package/dist/cjs/instance/bindings-smoldot-light.js +46 -26
- package/dist/cjs/instance/bindings.d.ts +8 -8
- package/dist/cjs/instance/instance.js +19 -25
- package/dist/cjs/instance/raw-instance.d.ts +1 -1
- package/dist/cjs/instance/raw-instance.js +3 -2
- package/dist/mjs/index-browser.js +66 -19
- package/dist/mjs/index-deno.js +79 -56
- package/dist/mjs/index-nodejs.js +91 -40
- package/dist/mjs/instance/autogen/wasm0.js +1 -1
- package/dist/mjs/instance/autogen/wasm1.js +1 -1
- package/dist/mjs/instance/autogen/wasm2.js +1 -1
- package/dist/mjs/instance/bindings-smoldot-light.d.ts +42 -2
- package/dist/mjs/instance/bindings-smoldot-light.js +46 -26
- package/dist/mjs/instance/bindings.d.ts +8 -8
- package/dist/mjs/instance/instance.js +19 -25
- package/dist/mjs/instance/raw-instance.d.ts +1 -1
- package/dist/mjs/instance/raw-instance.js +3 -2
- package/package.json +3 -3
package/dist/mjs/index-deno.js
CHANGED
|
@@ -99,7 +99,6 @@ function trustedBase64Decode(base64) {
|
|
|
99
99
|
* @throws {@link ConnectionError} If the multiaddress couldn't be parsed or contains an invalid protocol.
|
|
100
100
|
*/
|
|
101
101
|
function connect(config, forbidTcp, forbidWs, forbidNonLocalWs, forbidWss) {
|
|
102
|
-
let connection;
|
|
103
102
|
// Attempt to parse the multiaddress.
|
|
104
103
|
// TODO: remove support for `/wss` in a long time (https://github.com/paritytech/smoldot/issues/1940)
|
|
105
104
|
const wsParsed = config.address.match(/^\/(ip4|ip6|dns4|dns6|dns)\/(.*?)\/tcp\/(.*?)\/(ws|wss|tls\/ws)$/);
|
|
@@ -114,24 +113,72 @@ function connect(config, forbidTcp, forbidWs, forbidNonLocalWs, forbidWss) {
|
|
|
114
113
|
const url = (wsParsed[1] == 'ip6') ?
|
|
115
114
|
(proto + "://[" + wsParsed[2] + "]:" + wsParsed[3]) :
|
|
116
115
|
(proto + "://" + wsParsed[2] + ":" + wsParsed[3]);
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
116
|
+
const socket = new WebSocket(url);
|
|
117
|
+
socket.binaryType = 'arraybuffer';
|
|
118
|
+
const bufferedAmountCheck = { quenedUnreportedBytes: 0, nextTimeout: 10 };
|
|
119
|
+
const checkBufferedAmount = () => {
|
|
120
|
+
if (socket.readyState != 1)
|
|
121
|
+
return;
|
|
122
|
+
// Note that we might expect `bufferedAmount` to always be <= the sum of the lengths
|
|
123
|
+
// of all the data that has been sent, but that might not be the case. For this
|
|
124
|
+
// reason, we use `bufferedAmount` as a hint rather than a correct value.
|
|
125
|
+
const bufferedAmount = socket.bufferedAmount;
|
|
126
|
+
let wasSent = bufferedAmountCheck.quenedUnreportedBytes - bufferedAmount;
|
|
127
|
+
if (wasSent < 0)
|
|
128
|
+
wasSent = 0;
|
|
129
|
+
bufferedAmountCheck.quenedUnreportedBytes -= wasSent;
|
|
130
|
+
if (bufferedAmountCheck.quenedUnreportedBytes != 0) {
|
|
131
|
+
setTimeout(checkBufferedAmount, bufferedAmountCheck.nextTimeout);
|
|
132
|
+
bufferedAmountCheck.nextTimeout *= 2;
|
|
133
|
+
if (bufferedAmountCheck.nextTimeout > 500)
|
|
134
|
+
bufferedAmountCheck.nextTimeout = 500;
|
|
135
|
+
}
|
|
136
|
+
// Note: it is important to call `onWritableBytes` at the very end, as it might
|
|
137
|
+
// trigger a call to `send`.
|
|
138
|
+
if (wasSent != 0)
|
|
139
|
+
config.onWritableBytes(wasSent);
|
|
120
140
|
};
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
config.onOpen({ type: 'single-stream', handshake: 'multistream-select-noise-yamux' });
|
|
141
|
+
socket.onopen = () => {
|
|
142
|
+
config.onOpen({ type: 'single-stream', handshake: 'multistream-select-noise-yamux', initialWritableBytes: 1024 * 1024, writeClosable: false });
|
|
124
143
|
};
|
|
125
|
-
|
|
144
|
+
socket.onclose = (event) => {
|
|
126
145
|
const message = "Error code " + event.code + (!!event.reason ? (": " + event.reason) : "");
|
|
127
146
|
config.onConnectionReset(message);
|
|
128
147
|
};
|
|
129
|
-
|
|
148
|
+
socket.onmessage = (msg) => {
|
|
130
149
|
config.onMessage(new Uint8Array(msg.data));
|
|
131
150
|
};
|
|
151
|
+
return {
|
|
152
|
+
reset: () => {
|
|
153
|
+
// We can't set these fields to null because the TypeScript definitions don't
|
|
154
|
+
// allow it, but we can set them to dummy values.
|
|
155
|
+
socket.onopen = () => { };
|
|
156
|
+
socket.onclose = () => { };
|
|
157
|
+
socket.onmessage = () => { };
|
|
158
|
+
socket.onerror = () => { };
|
|
159
|
+
socket.close();
|
|
160
|
+
},
|
|
161
|
+
send: (data) => {
|
|
162
|
+
// The WebSocket library that we use seems to spontaneously transition connections
|
|
163
|
+
// to the "closed" state but not call the `onclosed` callback immediately. Calling
|
|
164
|
+
// `send` on that object throws an exception. In order to avoid panicking smoldot,
|
|
165
|
+
// we thus absorb any exception thrown here.
|
|
166
|
+
// See also <https://github.com/paritytech/smoldot/issues/2937>.
|
|
167
|
+
try {
|
|
168
|
+
socket.send(data);
|
|
169
|
+
if (bufferedAmountCheck.quenedUnreportedBytes == 0) {
|
|
170
|
+
bufferedAmountCheck.nextTimeout = 10;
|
|
171
|
+
setTimeout(checkBufferedAmount, 10);
|
|
172
|
+
}
|
|
173
|
+
bufferedAmountCheck.quenedUnreportedBytes += data.length;
|
|
174
|
+
}
|
|
175
|
+
catch (_error) { }
|
|
176
|
+
},
|
|
177
|
+
closeSend: () => { throw new Error('Wrong connection type'); },
|
|
178
|
+
openOutSubstream: () => { throw new Error('Wrong connection type'); }
|
|
179
|
+
};
|
|
132
180
|
}
|
|
133
181
|
else if (tcpParsed != null) {
|
|
134
|
-
// `net` module will be missing when we're not in NodeJS.
|
|
135
182
|
if (forbidTcp) {
|
|
136
183
|
throw new ConnectionError('TCP connections not available');
|
|
137
184
|
}
|
|
@@ -146,13 +193,12 @@ function connect(config, forbidTcp, forbidWs, forbidNonLocalWs, forbidWss) {
|
|
|
146
193
|
return null;
|
|
147
194
|
})
|
|
148
195
|
};
|
|
149
|
-
connection = { ty: 'tcp', socket };
|
|
150
196
|
socket.inner = socket.inner.then((established) => {
|
|
151
197
|
// TODO: at the time of writing of this comment, `setNoDelay` is still unstable
|
|
152
198
|
//established.setNoDelay();
|
|
153
199
|
if (socket.destroyed)
|
|
154
200
|
return established;
|
|
155
|
-
config.onOpen({ type: 'single-stream', handshake: 'multistream-select-noise-yamux' });
|
|
201
|
+
config.onOpen({ type: 'single-stream', handshake: 'multistream-select-noise-yamux', initialWritableBytes: 1024 * 1024, writeClosable: true });
|
|
156
202
|
// Spawns an asynchronous task that continuously reads from the socket.
|
|
157
203
|
// Every time data is read, the task re-executes itself in order to continue reading.
|
|
158
204
|
// The task ends automatically if an EOF or error is detected, which should also happen
|
|
@@ -184,53 +230,21 @@ function connect(config, forbidTcp, forbidWs, forbidNonLocalWs, forbidWss) {
|
|
|
184
230
|
read(new Uint8Array(1024));
|
|
185
231
|
return established;
|
|
186
232
|
});
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
if (connection.ty == 'websocket') {
|
|
194
|
-
// WebSocket
|
|
195
|
-
// We can't set these fields to null because the TypeScript definitions don't
|
|
196
|
-
// allow it, but we can set them to dummy values.
|
|
197
|
-
connection.socket.onopen = () => { };
|
|
198
|
-
connection.socket.onclose = () => { };
|
|
199
|
-
connection.socket.onmessage = () => { };
|
|
200
|
-
connection.socket.onerror = () => { };
|
|
201
|
-
connection.socket.close();
|
|
202
|
-
}
|
|
203
|
-
else {
|
|
204
|
-
// TCP
|
|
205
|
-
connection.socket.destroyed = true;
|
|
206
|
-
connection.socket.inner.then((connec) => connec.close());
|
|
207
|
-
}
|
|
208
|
-
},
|
|
209
|
-
send: (data) => {
|
|
210
|
-
if (connection.ty == 'websocket') {
|
|
211
|
-
// WebSocket
|
|
212
|
-
// The WebSocket library that we use seems to spontaneously transition connections
|
|
213
|
-
// to the "closed" state but not call the `onclosed` callback immediately. Calling
|
|
214
|
-
// `send` on that object throws an exception. In order to avoid panicking smoldot,
|
|
215
|
-
// we thus absorb any exception thrown here.
|
|
216
|
-
// See also <https://github.com/paritytech/smoldot/issues/2937>.
|
|
217
|
-
try {
|
|
218
|
-
connection.socket.send(data);
|
|
219
|
-
}
|
|
220
|
-
catch (_error) { }
|
|
221
|
-
}
|
|
222
|
-
else {
|
|
223
|
-
// TCP
|
|
224
|
-
// TODO: at the moment, sending data doesn't have any back-pressure mechanism; as such, we just buffer data indefinitely
|
|
233
|
+
return {
|
|
234
|
+
reset: () => {
|
|
235
|
+
socket.destroyed = true;
|
|
236
|
+
socket.inner.then((connec) => connec.close());
|
|
237
|
+
},
|
|
238
|
+
send: (data) => {
|
|
225
239
|
let dataCopy = Uint8Array.from(data); // Deep copy of the data
|
|
226
|
-
|
|
227
|
-
connection.socket.inner = connection.socket.inner.then((c) => __awaiter(this, void 0, void 0, function* () {
|
|
240
|
+
socket.inner = socket.inner.then((c) => __awaiter(this, void 0, void 0, function* () {
|
|
228
241
|
while (dataCopy.length > 0) {
|
|
229
242
|
if (socket.destroyed || c === null)
|
|
230
243
|
return c;
|
|
231
244
|
let outcome;
|
|
232
245
|
try {
|
|
233
246
|
outcome = yield c.write(dataCopy);
|
|
247
|
+
config.onWritableBytes(dataCopy.length);
|
|
234
248
|
}
|
|
235
249
|
catch (error) {
|
|
236
250
|
// The type of `error` is unclear, but we assume that it implements `Error`
|
|
@@ -250,8 +264,17 @@ function connect(config, forbidTcp, forbidWs, forbidNonLocalWs, forbidWss) {
|
|
|
250
264
|
}
|
|
251
265
|
return c;
|
|
252
266
|
}));
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
267
|
+
},
|
|
268
|
+
closeSend: () => {
|
|
269
|
+
socket.inner = socket.inner.then((c) => __awaiter(this, void 0, void 0, function* () {
|
|
270
|
+
yield (c === null || c === void 0 ? void 0 : c.closeWrite());
|
|
271
|
+
return c;
|
|
272
|
+
}));
|
|
273
|
+
},
|
|
274
|
+
openOutSubstream: () => { throw new Error('Wrong connection type'); }
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
else {
|
|
278
|
+
throw new ConnectionError('Unrecognized multiaddr format');
|
|
279
|
+
}
|
|
257
280
|
}
|
package/dist/mjs/index-nodejs.js
CHANGED
|
@@ -42,7 +42,7 @@ export function start(options) {
|
|
|
42
42
|
return performance.now();
|
|
43
43
|
},
|
|
44
44
|
getRandomValues: (buffer) => {
|
|
45
|
-
if (buffer.length >=
|
|
45
|
+
if (buffer.length >= 1024 * 1024)
|
|
46
46
|
throw new Error('getRandomValues buffer too large');
|
|
47
47
|
randomFillSync(buffer);
|
|
48
48
|
},
|
|
@@ -58,7 +58,6 @@ export function start(options) {
|
|
|
58
58
|
* @throws {@link ConnectionError} If the multiaddress couldn't be parsed or contains an invalid protocol.
|
|
59
59
|
*/
|
|
60
60
|
function connect(config, forbidTcp, forbidWs, forbidNonLocalWs, forbidWss) {
|
|
61
|
-
let connection;
|
|
62
61
|
// Attempt to parse the multiaddress.
|
|
63
62
|
// TODO: remove support for `/wss` in a long time (https://github.com/paritytech/smoldot/issues/1940)
|
|
64
63
|
const wsParsed = config.address.match(/^\/(ip4|ip6|dns4|dns6|dns)\/(.*?)\/tcp\/(.*?)\/(ws|wss|tls\/ws)$/);
|
|
@@ -75,8 +74,33 @@ function connect(config, forbidTcp, forbidWs, forbidNonLocalWs, forbidWss) {
|
|
|
75
74
|
(proto + "://" + wsParsed[2] + ":" + wsParsed[3]);
|
|
76
75
|
const socket = new WebSocket(url);
|
|
77
76
|
socket.binaryType = 'arraybuffer';
|
|
77
|
+
const bufferedAmountCheck = { quenedUnreportedBytes: 0, nextTimeout: 10 };
|
|
78
|
+
const checkBufferedAmount = () => {
|
|
79
|
+
if (socket.readyState != 1)
|
|
80
|
+
return;
|
|
81
|
+
// Note that we might expect `bufferedAmount` to always be <= the sum of the lengths
|
|
82
|
+
// of all the data that has been sent, but that seems to not be the case. It is
|
|
83
|
+
// unclear whether this is intended or a bug, but is is likely that `bufferedAmount`
|
|
84
|
+
// also includes WebSocket headers. For this reason, we use `bufferedAmount` as a hint
|
|
85
|
+
// rather than a correct value.
|
|
86
|
+
const bufferedAmount = socket.bufferedAmount;
|
|
87
|
+
let wasSent = bufferedAmountCheck.quenedUnreportedBytes - bufferedAmount;
|
|
88
|
+
if (wasSent < 0)
|
|
89
|
+
wasSent = 0;
|
|
90
|
+
bufferedAmountCheck.quenedUnreportedBytes -= wasSent;
|
|
91
|
+
if (bufferedAmountCheck.quenedUnreportedBytes != 0) {
|
|
92
|
+
setTimeout(checkBufferedAmount, bufferedAmountCheck.nextTimeout);
|
|
93
|
+
bufferedAmountCheck.nextTimeout *= 2;
|
|
94
|
+
if (bufferedAmountCheck.nextTimeout > 500)
|
|
95
|
+
bufferedAmountCheck.nextTimeout = 500;
|
|
96
|
+
}
|
|
97
|
+
// Note: it is important to call `onWritableBytes` at the very end, as it might
|
|
98
|
+
// trigger a call to `send`.
|
|
99
|
+
if (wasSent != 0)
|
|
100
|
+
config.onWritableBytes(wasSent);
|
|
101
|
+
};
|
|
78
102
|
socket.onopen = () => {
|
|
79
|
-
config.onOpen({ type: 'single-stream', handshake: 'multistream-select-noise-yamux' });
|
|
103
|
+
config.onOpen({ type: 'single-stream', handshake: 'multistream-select-noise-yamux', initialWritableBytes: 1024 * 1024, writeClosable: false });
|
|
80
104
|
};
|
|
81
105
|
socket.onclose = (event) => {
|
|
82
106
|
const message = "Error code " + event.code + (!!event.reason ? (": " + event.reason) : "");
|
|
@@ -96,7 +120,27 @@ function connect(config, forbidTcp, forbidWs, forbidNonLocalWs, forbidWss) {
|
|
|
96
120
|
socket.onmessage = (msg) => {
|
|
97
121
|
config.onMessage(new Uint8Array(msg.data));
|
|
98
122
|
};
|
|
99
|
-
|
|
123
|
+
return {
|
|
124
|
+
reset: () => {
|
|
125
|
+
// We can't set these fields to null because the TypeScript definitions don't
|
|
126
|
+
// allow it, but we can set them to dummy values.
|
|
127
|
+
socket.onopen = () => { };
|
|
128
|
+
socket.onclose = () => { };
|
|
129
|
+
socket.onmessage = () => { };
|
|
130
|
+
socket.onerror = () => { };
|
|
131
|
+
socket.close();
|
|
132
|
+
},
|
|
133
|
+
send: (data) => {
|
|
134
|
+
socket.send(data);
|
|
135
|
+
if (bufferedAmountCheck.quenedUnreportedBytes == 0) {
|
|
136
|
+
bufferedAmountCheck.nextTimeout = 10;
|
|
137
|
+
setTimeout(checkBufferedAmount, 10);
|
|
138
|
+
}
|
|
139
|
+
bufferedAmountCheck.quenedUnreportedBytes += data.length;
|
|
140
|
+
},
|
|
141
|
+
closeSend: () => { throw new Error('Wrong connection type'); },
|
|
142
|
+
openOutSubstream: () => { throw new Error('Wrong connection type'); }
|
|
143
|
+
};
|
|
100
144
|
}
|
|
101
145
|
else if (tcpParsed != null) {
|
|
102
146
|
// `net` module will be missing when we're not in NodeJS.
|
|
@@ -107,14 +151,18 @@ function connect(config, forbidTcp, forbidWs, forbidNonLocalWs, forbidWss) {
|
|
|
107
151
|
host: tcpParsed[2],
|
|
108
152
|
port: parseInt(tcpParsed[3], 10),
|
|
109
153
|
});
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
154
|
+
// Number of bytes queued using `socket.write` and where `write` has returned false.
|
|
155
|
+
const drainingBytes = { num: 0 };
|
|
156
|
+
socket.setNoDelay();
|
|
157
|
+
socket.on('connect', () => {
|
|
113
158
|
if (socket.destroyed)
|
|
114
159
|
return;
|
|
115
|
-
config.onOpen({
|
|
160
|
+
config.onOpen({
|
|
161
|
+
type: 'single-stream', handshake: 'multistream-select-noise-yamux',
|
|
162
|
+
initialWritableBytes: socket.writableHighWaterMark, writeClosable: true
|
|
163
|
+
});
|
|
116
164
|
});
|
|
117
|
-
|
|
165
|
+
socket.on('close', (hasError) => {
|
|
118
166
|
if (socket.destroyed)
|
|
119
167
|
return;
|
|
120
168
|
// NodeJS doesn't provide a reason why the closing happened, but only
|
|
@@ -122,43 +170,46 @@ function connect(config, forbidTcp, forbidWs, forbidNonLocalWs, forbidWss) {
|
|
|
122
170
|
const message = hasError ? "Error" : "Closed gracefully";
|
|
123
171
|
config.onConnectionReset(message);
|
|
124
172
|
});
|
|
125
|
-
|
|
126
|
-
|
|
173
|
+
socket.on('error', () => { });
|
|
174
|
+
socket.on('data', (message) => {
|
|
127
175
|
if (socket.destroyed)
|
|
128
176
|
return;
|
|
129
177
|
config.onMessage(new Uint8Array(message.buffer));
|
|
130
178
|
});
|
|
179
|
+
socket.on('drain', () => {
|
|
180
|
+
// The bytes queued using `socket.write` and where `write` has returned false have now
|
|
181
|
+
// been sent. Notify the API that it can write more data.
|
|
182
|
+
if (socket.destroyed)
|
|
183
|
+
return;
|
|
184
|
+
const val = drainingBytes.num;
|
|
185
|
+
drainingBytes.num = 0;
|
|
186
|
+
config.onWritableBytes(val);
|
|
187
|
+
});
|
|
188
|
+
return {
|
|
189
|
+
reset: () => {
|
|
190
|
+
socket.destroy();
|
|
191
|
+
},
|
|
192
|
+
send: (data) => {
|
|
193
|
+
const dataLen = data.length;
|
|
194
|
+
const allWritten = socket.write(data);
|
|
195
|
+
if (allWritten) {
|
|
196
|
+
setImmediate(() => {
|
|
197
|
+
if (!socket.writable)
|
|
198
|
+
return;
|
|
199
|
+
config.onWritableBytes(dataLen);
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
drainingBytes.num += dataLen;
|
|
204
|
+
}
|
|
205
|
+
},
|
|
206
|
+
closeSend: () => {
|
|
207
|
+
socket.end();
|
|
208
|
+
},
|
|
209
|
+
openOutSubstream: () => { throw new Error('Wrong connection type'); }
|
|
210
|
+
};
|
|
131
211
|
}
|
|
132
212
|
else {
|
|
133
213
|
throw new ConnectionError('Unrecognized multiaddr format');
|
|
134
214
|
}
|
|
135
|
-
return {
|
|
136
|
-
reset: () => {
|
|
137
|
-
if (connection.ty == 'websocket') {
|
|
138
|
-
// WebSocket
|
|
139
|
-
// We can't set these fields to null because the TypeScript definitions don't
|
|
140
|
-
// allow it, but we can set them to dummy values.
|
|
141
|
-
connection.socket.onopen = () => { };
|
|
142
|
-
connection.socket.onclose = () => { };
|
|
143
|
-
connection.socket.onmessage = () => { };
|
|
144
|
-
connection.socket.onerror = () => { };
|
|
145
|
-
connection.socket.close();
|
|
146
|
-
}
|
|
147
|
-
else {
|
|
148
|
-
// TCP
|
|
149
|
-
connection.socket.destroy();
|
|
150
|
-
}
|
|
151
|
-
},
|
|
152
|
-
send: (data) => {
|
|
153
|
-
if (connection.ty == 'websocket') {
|
|
154
|
-
// WebSocket
|
|
155
|
-
connection.socket.send(data);
|
|
156
|
-
}
|
|
157
|
-
else {
|
|
158
|
-
// TCP
|
|
159
|
-
connection.socket.write(data);
|
|
160
|
-
}
|
|
161
|
-
},
|
|
162
|
-
openOutSubstream: () => { throw new Error('Wrong connection type'); }
|
|
163
|
-
};
|
|
164
215
|
}
|