Comparing version 2.0.10 to 2.0.11
@@ -71,3 +71,3 @@ import { Client, ClientOptions, SmoldotBytecode } from '../public-types.js'; | ||
*/ | ||
send(data: Uint8Array, streamId?: number): void; | ||
send(data: Array<Uint8Array>, streamId?: number): void; | ||
/** | ||
@@ -74,0 +74,0 @@ * Closes the writing side of the given stream of the given connection. |
@@ -72,3 +72,3 @@ /** | ||
streamId?: number; | ||
data: Uint8Array; | ||
data: Array<Uint8Array>; | ||
} | { | ||
@@ -75,0 +75,0 @@ ty: "stream-send-close"; |
@@ -253,5 +253,11 @@ "use strict"; | ||
const instance = state.instance; | ||
const mem = new Uint8Array(instance.exports.memory.buffer); | ||
ptr >>>= 0; | ||
len >>>= 0; | ||
const data = new Uint8Array(instance.exports.memory.buffer).slice(ptr, ptr + len); | ||
const data = new Array(); | ||
for (let i = 0; i < len; ++i) { | ||
const bufPtr = buffer.readUInt32LE(mem, ptr + 8 * i); | ||
const bufLen = buffer.readUInt32LE(mem, ptr + 8 * i + 4); | ||
data.push(mem.slice(bufPtr, bufPtr + bufLen)); | ||
} | ||
// TODO: docs says the streamId is provided only for multi-stream connections, but here it's always provided | ||
@@ -258,0 +264,0 @@ eventCallback({ ty: "stream-send", connectionId, streamId, data }); |
@@ -32,2 +32,15 @@ "use strict"; | ||
options.forbidTcp = true; | ||
// When in a secure context, browsers refuse to open non-secure WebSocket connections to | ||
// non-localhost. There is an exception if the page is localhost, in which case all connections | ||
// are allowed. | ||
// Detecting this ahead of time is better for the overall health of the client, as it will | ||
// avoid storing in memory addresses that it knows it can't connect to. | ||
// The condition below is a hint, and false-positives or false-negatives are not fundamentally | ||
// an issue. | ||
if ((typeof isSecureContext === 'boolean' && isSecureContext) && typeof location !== undefined) { | ||
const loc = location.toString(); | ||
if (loc.indexOf('localhost') !== -1 && loc.indexOf('127.0.0.1') !== -1 && loc.indexOf('::1') !== -1) { | ||
options.forbidNonLocalWs = true; | ||
} | ||
} | ||
return (0, client_js_1.start)(options, options.bytecode, { | ||
@@ -146,3 +159,2 @@ performanceNow: () => { | ||
send: (data) => { | ||
connection.send(data); | ||
if (bufferedAmountCheck.quenedUnreportedBytes == 0) { | ||
@@ -152,3 +164,6 @@ bufferedAmountCheck.nextTimeout = 10; | ||
} | ||
bufferedAmountCheck.quenedUnreportedBytes += data.length; | ||
for (const buffer of data) { | ||
bufferedAmountCheck.quenedUnreportedBytes += buffer.length; | ||
} | ||
connection.send(new Blob(data)); | ||
}, | ||
@@ -424,4 +439,6 @@ closeSend: () => { throw new Error('Wrong connection type'); }, | ||
const channel = state.dataChannels.get(streamId); | ||
channel.channel.send(data); | ||
channel.bufferedBytes += data.length; | ||
for (const buffer of data) { | ||
channel.bufferedBytes += buffer.length; | ||
} | ||
channel.channel.send(new Blob(data)); | ||
}, | ||
@@ -428,0 +445,0 @@ closeSend: () => { throw new Error('Wrong connection type'); }, |
@@ -108,3 +108,2 @@ "use strict"; | ||
try { | ||
socket.send(data); | ||
if (bufferedAmountCheck.quenedUnreportedBytes == 0) { | ||
@@ -114,3 +113,6 @@ bufferedAmountCheck.nextTimeout = 10; | ||
} | ||
bufferedAmountCheck.quenedUnreportedBytes += data.length; | ||
for (const buffer of data) { | ||
bufferedAmountCheck.quenedUnreportedBytes += buffer.length; | ||
} | ||
socket.send(new Blob(data)); | ||
} | ||
@@ -177,27 +179,31 @@ catch (_error) { } | ||
send: (data) => { | ||
let dataCopy = Uint8Array.from(data); // Deep copy of the data | ||
let dataCopy = data.map((buf) => Uint8Array.from(buf)); // Deep copy of the data | ||
socket.inner = socket.inner.then((c) => __awaiter(this, void 0, void 0, function* () { | ||
while (dataCopy.length > 0) { | ||
if (socket.destroyed || c === null) | ||
return c; | ||
let outcome; | ||
try { | ||
outcome = yield c.write(dataCopy); | ||
config.onWritableBytes(dataCopy.length); | ||
for (let buffer of dataCopy) { | ||
while (buffer.length > 0) { | ||
if (socket.destroyed || c === null) | ||
return c; | ||
let outcome; | ||
try { | ||
outcome = yield c.write(buffer); | ||
config.onWritableBytes(buffer.length); | ||
} | ||
catch (error) { | ||
// The type of `error` is unclear, but we assume that it | ||
// implements `Error` | ||
outcome = error.toString(); | ||
} | ||
if (typeof outcome !== 'number') { | ||
// The socket is reported closed, but `socket.destroyed` is still | ||
// `false` (see check above). As such, we must inform the | ||
// inner layers. | ||
socket.destroyed = true; | ||
config.onConnectionReset(outcome); | ||
return c; | ||
} | ||
// Note that, contrary to `read`, it is possible for `outcome` to be 0. | ||
// This happen if the write had to be interrupted, and the only thing | ||
// we have to do is try writing again. | ||
buffer = buffer.slice(outcome); | ||
} | ||
catch (error) { | ||
// The type of `error` is unclear, but we assume that it implements `Error` | ||
outcome = error.toString(); | ||
} | ||
if (typeof outcome !== 'number') { | ||
// The socket is reported closed, but `socket.destroyed` is still | ||
// `false` (see check above). As such, we must inform the inner layers. | ||
socket.destroyed = true; | ||
config.onConnectionReset(outcome); | ||
return c; | ||
} | ||
// Note that, contrary to `read`, it is possible for `outcome` to be 0. | ||
// This happen if the write had to be interrupted, and the only thing | ||
// we have to do is try writing again. | ||
dataCopy = dataCopy.slice(outcome); | ||
} | ||
@@ -204,0 +210,0 @@ return c; |
@@ -109,3 +109,2 @@ "use strict"; | ||
send: (data) => { | ||
socket.send(data); | ||
if (bufferedAmountCheck.quenedUnreportedBytes == 0) { | ||
@@ -115,3 +114,6 @@ bufferedAmountCheck.nextTimeout = 10; | ||
} | ||
bufferedAmountCheck.quenedUnreportedBytes += data.length; | ||
for (const buffer of data) { | ||
socket.send(buffer); | ||
bufferedAmountCheck.quenedUnreportedBytes += buffer.length; | ||
} | ||
}, | ||
@@ -163,14 +165,16 @@ closeSend: () => { throw new Error('Wrong connection type'); }, | ||
send: (data) => { | ||
const dataLen = data.length; | ||
const allWritten = socket.write(data); | ||
if (allWritten) { | ||
setImmediate(() => { | ||
if (!socket.writable) | ||
return; | ||
config.onWritableBytes(dataLen); | ||
}); | ||
for (const buffer of data) { | ||
const bufferLen = buffer.length; | ||
const allWritten = socket.write(buffer); | ||
if (allWritten) { | ||
setImmediate(() => { | ||
if (!socket.writable) | ||
return; | ||
config.onWritableBytes(bufferLen); | ||
}); | ||
} | ||
else { | ||
drainingBytes.num += bufferLen; | ||
} | ||
} | ||
else { | ||
drainingBytes.num += dataLen; | ||
} | ||
}, | ||
@@ -177,0 +181,0 @@ closeSend: () => { |
@@ -71,3 +71,3 @@ import { Client, ClientOptions, SmoldotBytecode } from '../public-types.js'; | ||
*/ | ||
send(data: Uint8Array, streamId?: number): void; | ||
send(data: Array<Uint8Array>, streamId?: number): void; | ||
/** | ||
@@ -74,0 +74,0 @@ * Closes the writing side of the given stream of the given connection. |
@@ -72,3 +72,3 @@ /** | ||
streamId?: number; | ||
data: Uint8Array; | ||
data: Array<Uint8Array>; | ||
} | { | ||
@@ -75,0 +75,0 @@ ty: "stream-send-close"; |
@@ -250,5 +250,11 @@ // Smoldot | ||
const instance = state.instance; | ||
const mem = new Uint8Array(instance.exports.memory.buffer); | ||
ptr >>>= 0; | ||
len >>>= 0; | ||
const data = new Uint8Array(instance.exports.memory.buffer).slice(ptr, ptr + len); | ||
const data = new Array(); | ||
for (let i = 0; i < len; ++i) { | ||
const bufPtr = buffer.readUInt32LE(mem, ptr + 8 * i); | ||
const bufLen = buffer.readUInt32LE(mem, ptr + 8 * i + 4); | ||
data.push(mem.slice(bufPtr, bufPtr + bufLen)); | ||
} | ||
// TODO: docs says the streamId is provided only for multi-stream connections, but here it's always provided | ||
@@ -255,0 +261,0 @@ eventCallback({ ty: "stream-send", connectionId, streamId, data }); |
@@ -24,2 +24,15 @@ // Smoldot | ||
options.forbidTcp = true; | ||
// When in a secure context, browsers refuse to open non-secure WebSocket connections to | ||
// non-localhost. There is an exception if the page is localhost, in which case all connections | ||
// are allowed. | ||
// Detecting this ahead of time is better for the overall health of the client, as it will | ||
// avoid storing in memory addresses that it knows it can't connect to. | ||
// The condition below is a hint, and false-positives or false-negatives are not fundamentally | ||
// an issue. | ||
if ((typeof isSecureContext === 'boolean' && isSecureContext) && typeof location !== undefined) { | ||
const loc = location.toString(); | ||
if (loc.indexOf('localhost') !== -1 && loc.indexOf('127.0.0.1') !== -1 && loc.indexOf('::1') !== -1) { | ||
options.forbidNonLocalWs = true; | ||
} | ||
} | ||
return innerStart(options, options.bytecode, { | ||
@@ -137,3 +150,2 @@ performanceNow: () => { | ||
send: (data) => { | ||
connection.send(data); | ||
if (bufferedAmountCheck.quenedUnreportedBytes == 0) { | ||
@@ -143,3 +155,6 @@ bufferedAmountCheck.nextTimeout = 10; | ||
} | ||
bufferedAmountCheck.quenedUnreportedBytes += data.length; | ||
for (const buffer of data) { | ||
bufferedAmountCheck.quenedUnreportedBytes += buffer.length; | ||
} | ||
connection.send(new Blob(data)); | ||
}, | ||
@@ -415,4 +430,6 @@ closeSend: () => { throw new Error('Wrong connection type'); }, | ||
const channel = state.dataChannels.get(streamId); | ||
channel.channel.send(data); | ||
channel.bufferedBytes += data.length; | ||
for (const buffer of data) { | ||
channel.bufferedBytes += buffer.length; | ||
} | ||
channel.channel.send(new Blob(data)); | ||
}, | ||
@@ -419,0 +436,0 @@ closeSend: () => { throw new Error('Wrong connection type'); }, |
@@ -99,3 +99,2 @@ // Smoldot | ||
try { | ||
socket.send(data); | ||
if (bufferedAmountCheck.quenedUnreportedBytes == 0) { | ||
@@ -105,3 +104,6 @@ bufferedAmountCheck.nextTimeout = 10; | ||
} | ||
bufferedAmountCheck.quenedUnreportedBytes += data.length; | ||
for (const buffer of data) { | ||
bufferedAmountCheck.quenedUnreportedBytes += buffer.length; | ||
} | ||
socket.send(new Blob(data)); | ||
} | ||
@@ -168,27 +170,31 @@ catch (_error) { } | ||
send: (data) => { | ||
let dataCopy = Uint8Array.from(data); // Deep copy of the data | ||
let dataCopy = data.map((buf) => Uint8Array.from(buf)); // Deep copy of the data | ||
socket.inner = socket.inner.then((c) => __awaiter(this, void 0, void 0, function* () { | ||
while (dataCopy.length > 0) { | ||
if (socket.destroyed || c === null) | ||
return c; | ||
let outcome; | ||
try { | ||
outcome = yield c.write(dataCopy); | ||
config.onWritableBytes(dataCopy.length); | ||
for (let buffer of dataCopy) { | ||
while (buffer.length > 0) { | ||
if (socket.destroyed || c === null) | ||
return c; | ||
let outcome; | ||
try { | ||
outcome = yield c.write(buffer); | ||
config.onWritableBytes(buffer.length); | ||
} | ||
catch (error) { | ||
// The type of `error` is unclear, but we assume that it | ||
// implements `Error` | ||
outcome = error.toString(); | ||
} | ||
if (typeof outcome !== 'number') { | ||
// The socket is reported closed, but `socket.destroyed` is still | ||
// `false` (see check above). As such, we must inform the | ||
// inner layers. | ||
socket.destroyed = true; | ||
config.onConnectionReset(outcome); | ||
return c; | ||
} | ||
// Note that, contrary to `read`, it is possible for `outcome` to be 0. | ||
// This happen if the write had to be interrupted, and the only thing | ||
// we have to do is try writing again. | ||
buffer = buffer.slice(outcome); | ||
} | ||
catch (error) { | ||
// The type of `error` is unclear, but we assume that it implements `Error` | ||
outcome = error.toString(); | ||
} | ||
if (typeof outcome !== 'number') { | ||
// The socket is reported closed, but `socket.destroyed` is still | ||
// `false` (see check above). As such, we must inform the inner layers. | ||
socket.destroyed = true; | ||
config.onConnectionReset(outcome); | ||
return c; | ||
} | ||
// Note that, contrary to `read`, it is possible for `outcome` to be 0. | ||
// This happen if the write had to be interrupted, and the only thing | ||
// we have to do is try writing again. | ||
dataCopy = dataCopy.slice(outcome); | ||
} | ||
@@ -195,0 +201,0 @@ return c; |
@@ -100,3 +100,2 @@ // Smoldot | ||
send: (data) => { | ||
socket.send(data); | ||
if (bufferedAmountCheck.quenedUnreportedBytes == 0) { | ||
@@ -106,3 +105,6 @@ bufferedAmountCheck.nextTimeout = 10; | ||
} | ||
bufferedAmountCheck.quenedUnreportedBytes += data.length; | ||
for (const buffer of data) { | ||
socket.send(buffer); | ||
bufferedAmountCheck.quenedUnreportedBytes += buffer.length; | ||
} | ||
}, | ||
@@ -154,14 +156,16 @@ closeSend: () => { throw new Error('Wrong connection type'); }, | ||
send: (data) => { | ||
const dataLen = data.length; | ||
const allWritten = socket.write(data); | ||
if (allWritten) { | ||
setImmediate(() => { | ||
if (!socket.writable) | ||
return; | ||
config.onWritableBytes(dataLen); | ||
}); | ||
for (const buffer of data) { | ||
const bufferLen = buffer.length; | ||
const allWritten = socket.write(buffer); | ||
if (allWritten) { | ||
setImmediate(() => { | ||
if (!socket.writable) | ||
return; | ||
config.onWritableBytes(bufferLen); | ||
}); | ||
} | ||
else { | ||
drainingBytes.num += bufferLen; | ||
} | ||
} | ||
else { | ||
drainingBytes.num += dataLen; | ||
} | ||
}, | ||
@@ -168,0 +172,0 @@ closeSend: () => { |
{ | ||
"name": "smoldot", | ||
"version": "2.0.10", | ||
"version": "2.0.11", | ||
"description": "Light client that connects to Polkadot and Substrate-based blockchains", | ||
@@ -5,0 +5,0 @@ "contributors": [ |
@@ -76,3 +76,3 @@ # Light client for Polkadot and Substrate-based chains | ||
In order to help with this, it possible to use smoldot in conjunction with a worker. | ||
In order to help with this, it is possible to use smoldot in conjunction with a worker. | ||
To do so, you must first create a worker. Since creating a worker has some subtle differences | ||
@@ -79,0 +79,0 @@ depending on the platform, this is outside of the responsibility of smoldot. |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
29672
6155615