smoldot 1.0.4 → 1.0.6

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 (116) hide show
  1. package/README.md +58 -0
  2. package/dist/cjs/bytecode-browser.d.ts +5 -0
  3. package/dist/cjs/bytecode-browser.js +42 -0
  4. package/dist/cjs/bytecode-deno.d.ts +5 -0
  5. package/dist/cjs/bytecode-deno.js +87 -0
  6. package/dist/cjs/bytecode-nodejs.d.ts +5 -0
  7. package/dist/cjs/bytecode-nodejs.js +41 -0
  8. package/dist/cjs/index-browser.d.ts +2 -2
  9. package/dist/cjs/index-browser.js +10 -507
  10. package/dist/cjs/index-deno.d.ts +2 -2
  11. package/dist/cjs/index-deno.js +10 -283
  12. package/dist/cjs/index-nodejs.d.ts +2 -2
  13. package/dist/cjs/index-nodejs.js +10 -211
  14. package/dist/cjs/internals/bytecode/wasm0.js +4 -0
  15. package/dist/cjs/internals/bytecode/wasm1.js +4 -0
  16. package/dist/cjs/internals/bytecode/wasm2.js +4 -0
  17. package/dist/cjs/{instance/bindings-smoldot-light.d.ts → internals/client.d.ts} +15 -34
  18. package/dist/cjs/internals/client.js +376 -0
  19. package/dist/cjs/internals/local-instance.d.ts +144 -0
  20. package/dist/cjs/internals/local-instance.js +566 -0
  21. package/dist/cjs/internals/remote-instance.d.ts +38 -0
  22. package/dist/cjs/internals/remote-instance.js +374 -0
  23. package/dist/cjs/no-auto-bytecode-browser.d.ts +11 -0
  24. package/dist/cjs/no-auto-bytecode-browser.js +481 -0
  25. package/dist/cjs/no-auto-bytecode-deno.d.ts +10 -0
  26. package/dist/cjs/no-auto-bytecode-deno.js +220 -0
  27. package/dist/cjs/no-auto-bytecode-nodejs.d.ts +10 -0
  28. package/dist/cjs/no-auto-bytecode-nodejs.js +189 -0
  29. package/dist/cjs/{client.d.ts → public-types.d.ts} +51 -3
  30. package/dist/cjs/public-types.js +76 -0
  31. package/dist/cjs/worker-browser.d.ts +11 -0
  32. package/dist/cjs/worker-browser.js +63 -0
  33. package/dist/cjs/worker-deno.d.ts +11 -0
  34. package/dist/cjs/worker-deno.js +54 -0
  35. package/dist/cjs/worker-nodejs.d.ts +11 -0
  36. package/dist/cjs/worker-nodejs.js +55 -0
  37. package/dist/mjs/bytecode-browser.d.ts +5 -0
  38. package/dist/mjs/bytecode-browser.js +38 -0
  39. package/dist/mjs/bytecode-deno.d.ts +5 -0
  40. package/dist/mjs/bytecode-deno.js +83 -0
  41. package/dist/mjs/bytecode-nodejs.d.ts +5 -0
  42. package/dist/mjs/bytecode-nodejs.js +37 -0
  43. package/dist/mjs/index-browser.d.ts +2 -2
  44. package/dist/mjs/index-browser.js +4 -501
  45. package/dist/mjs/index-deno.d.ts +2 -2
  46. package/dist/mjs/index-deno.js +4 -277
  47. package/dist/mjs/index-nodejs.d.ts +2 -2
  48. package/dist/mjs/index-nodejs.js +4 -205
  49. package/dist/mjs/internals/bytecode/wasm0.js +1 -0
  50. package/dist/mjs/internals/bytecode/wasm1.js +1 -0
  51. package/dist/mjs/internals/bytecode/wasm2.js +1 -0
  52. package/dist/mjs/{instance/bindings-smoldot-light.d.ts → internals/client.d.ts} +15 -34
  53. package/dist/mjs/internals/client.js +372 -0
  54. package/dist/mjs/internals/local-instance.d.ts +144 -0
  55. package/dist/mjs/internals/local-instance.js +561 -0
  56. package/dist/mjs/internals/remote-instance.d.ts +38 -0
  57. package/dist/mjs/internals/remote-instance.js +369 -0
  58. package/dist/mjs/no-auto-bytecode-browser.d.ts +11 -0
  59. package/dist/mjs/no-auto-bytecode-browser.js +471 -0
  60. package/dist/mjs/no-auto-bytecode-deno.d.ts +10 -0
  61. package/dist/mjs/no-auto-bytecode-deno.js +210 -0
  62. package/dist/mjs/no-auto-bytecode-nodejs.d.ts +10 -0
  63. package/dist/mjs/no-auto-bytecode-nodejs.js +179 -0
  64. package/dist/mjs/{client.d.ts → public-types.d.ts} +51 -3
  65. package/dist/mjs/public-types.js +67 -0
  66. package/dist/mjs/worker-browser.d.ts +11 -0
  67. package/dist/mjs/worker-browser.js +59 -0
  68. package/dist/mjs/worker-deno.d.ts +11 -0
  69. package/dist/mjs/worker-deno.js +50 -0
  70. package/dist/mjs/worker-nodejs.d.ts +11 -0
  71. package/dist/mjs/worker-nodejs.js +51 -0
  72. package/package.json +40 -8
  73. package/dist/cjs/client.js +0 -172
  74. package/dist/cjs/instance/autogen/wasm0.js +0 -4
  75. package/dist/cjs/instance/autogen/wasm1.js +0 -4
  76. package/dist/cjs/instance/autogen/wasm2.js +0 -4
  77. package/dist/cjs/instance/bindings-smoldot-light.js +0 -285
  78. package/dist/cjs/instance/bindings-wasi.d.ts +0 -27
  79. package/dist/cjs/instance/bindings-wasi.js +0 -172
  80. package/dist/cjs/instance/bindings.d.ts +0 -31
  81. package/dist/cjs/instance/bindings.js +0 -5
  82. package/dist/cjs/instance/instance.d.ts +0 -45
  83. package/dist/cjs/instance/instance.js +0 -277
  84. package/dist/cjs/instance/raw-instance.d.ts +0 -56
  85. package/dist/cjs/instance/raw-instance.js +0 -129
  86. package/dist/mjs/client.js +0 -162
  87. package/dist/mjs/instance/autogen/wasm0.js +0 -1
  88. package/dist/mjs/instance/autogen/wasm1.js +0 -1
  89. package/dist/mjs/instance/autogen/wasm2.js +0 -1
  90. package/dist/mjs/instance/bindings-smoldot-light.js +0 -280
  91. package/dist/mjs/instance/bindings-wasi.d.ts +0 -27
  92. package/dist/mjs/instance/bindings-wasi.js +0 -170
  93. package/dist/mjs/instance/bindings.d.ts +0 -31
  94. package/dist/mjs/instance/bindings.js +0 -4
  95. package/dist/mjs/instance/instance.d.ts +0 -45
  96. package/dist/mjs/instance/instance.js +0 -269
  97. package/dist/mjs/instance/raw-instance.d.ts +0 -56
  98. package/dist/mjs/instance/raw-instance.js +0 -124
  99. /package/dist/cjs/{base64.d.ts → internals/base64.d.ts} +0 -0
  100. /package/dist/cjs/{base64.js → internals/base64.js} +0 -0
  101. /package/dist/cjs/{instance → internals}/buffer.d.ts +0 -0
  102. /package/dist/cjs/{instance → internals}/buffer.js +0 -0
  103. /package/dist/cjs/{instance/autogen → internals/bytecode}/wasm.d.ts +0 -0
  104. /package/dist/cjs/{instance/autogen → internals/bytecode}/wasm.js +0 -0
  105. /package/dist/cjs/{instance/autogen → internals/bytecode}/wasm0.d.ts +0 -0
  106. /package/dist/cjs/{instance/autogen → internals/bytecode}/wasm1.d.ts +0 -0
  107. /package/dist/cjs/{instance/autogen → internals/bytecode}/wasm2.d.ts +0 -0
  108. /package/dist/mjs/{base64.d.ts → internals/base64.d.ts} +0 -0
  109. /package/dist/mjs/{base64.js → internals/base64.js} +0 -0
  110. /package/dist/mjs/{instance → internals}/buffer.d.ts +0 -0
  111. /package/dist/mjs/{instance → internals}/buffer.js +0 -0
  112. /package/dist/mjs/{instance/autogen → internals/bytecode}/wasm.d.ts +0 -0
  113. /package/dist/mjs/{instance/autogen → internals/bytecode}/wasm.js +0 -0
  114. /package/dist/mjs/{instance/autogen → internals/bytecode}/wasm0.d.ts +0 -0
  115. /package/dist/mjs/{instance/autogen → internals/bytecode}/wasm1.d.ts +0 -0
  116. /package/dist/mjs/{instance/autogen → internals/bytecode}/wasm2.d.ts +0 -0
@@ -1,280 +0,0 @@
1
- // Smoldot
2
- // Copyright (C) 2019-2022 Parity Technologies (UK) Ltd.
3
- // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
4
- // This program is free software: you can redistribute it and/or modify
5
- // it under the terms of the GNU General Public License as published by
6
- // the Free Software Foundation, either version 3 of the License, or
7
- // (at your option) any later version.
8
- // This program is distributed in the hope that it will be useful,
9
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
10
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
- // GNU General Public License for more details.
12
- // You should have received a copy of the GNU General Public License
13
- // along with this program. If not, see <http://www.gnu.org/licenses/>.
14
- //! Exports a function that provides bindings for the bindings found in the Rust part of the code.
15
- //!
16
- //! In order to use this code, call the function passing an object, then fill the `instance` field
17
- //! of that object with the Wasm instance.
18
- import * as buffer from './buffer.js';
19
- /**
20
- * Emitted by `connect` if the multiaddress couldn't be parsed or contains an invalid protocol.
21
- *
22
- * @see connect
23
- */
24
- export class ConnectionError extends Error {
25
- constructor(message) {
26
- super(message);
27
- }
28
- }
29
- export default function (config) {
30
- // Used below to store the list of all connections.
31
- // The indices within this array are chosen by the Rust code.
32
- let connections = {};
33
- // Object containing a boolean indicating whether the `killAll` function has been invoked by
34
- // the user.
35
- const killedTracked = { killed: false };
36
- const killAll = () => {
37
- killedTracked.killed = true;
38
- // TODO: kill timers as well?
39
- for (const connection in connections) {
40
- connections[connection].reset();
41
- delete connections[connection];
42
- }
43
- };
44
- const imports = {
45
- // Must exit with an error. A human-readable message can be found in the WebAssembly
46
- // memory in the given buffer.
47
- panic: (ptr, len) => {
48
- const instance = config.instance;
49
- ptr >>>= 0;
50
- len >>>= 0;
51
- const message = buffer.utf8BytesToString(new Uint8Array(instance.exports.memory.buffer), ptr, len);
52
- config.onPanic(message);
53
- },
54
- buffer_size: (bufferIndex) => {
55
- const buf = config.bufferIndices[bufferIndex];
56
- return buf.byteLength;
57
- },
58
- buffer_copy: (bufferIndex, targetPtr) => {
59
- const instance = config.instance;
60
- targetPtr = targetPtr >>> 0;
61
- const buf = config.bufferIndices[bufferIndex];
62
- new Uint8Array(instance.exports.memory.buffer).set(buf, targetPtr);
63
- },
64
- advance_execution_ready: () => {
65
- config.advanceExecutionReadyCallback();
66
- },
67
- // Used by the Rust side to notify that a JSON-RPC response or subscription notification
68
- // is available in the queue of JSON-RPC responses.
69
- json_rpc_responses_non_empty: (chainId) => {
70
- if (killedTracked.killed)
71
- return;
72
- config.jsonRpcResponsesNonEmptyCallback(chainId);
73
- },
74
- // Used by the Rust side to emit a log entry.
75
- // See also the `max_log_level` parameter in the configuration.
76
- log: (level, targetPtr, targetLen, messagePtr, messageLen) => {
77
- if (killedTracked.killed)
78
- return;
79
- const instance = config.instance;
80
- targetPtr >>>= 0;
81
- targetLen >>>= 0;
82
- messagePtr >>>= 0;
83
- messageLen >>>= 0;
84
- if (config.logCallback) {
85
- const mem = new Uint8Array(instance.exports.memory.buffer);
86
- let target = buffer.utf8BytesToString(mem, targetPtr, targetLen);
87
- let message = buffer.utf8BytesToString(mem, messagePtr, messageLen);
88
- config.logCallback(level, target, message);
89
- }
90
- },
91
- // Must call `timer_finished` after the given number of milliseconds has elapsed.
92
- start_timer: (ms) => {
93
- if (killedTracked.killed)
94
- return;
95
- const instance = config.instance;
96
- // In both NodeJS and browsers, if `setTimeout` is called with a value larger than
97
- // 2147483647, the delay is for some reason instead set to 1.
98
- // As mentioned in the documentation of `start_timer`, it is acceptable to end the
99
- // timer before the given number of milliseconds has passed.
100
- if (ms > 2147483647)
101
- ms = 2147483647;
102
- // In browsers, `setTimeout` works as expected when `ms` equals 0. However, NodeJS
103
- // requires a minimum of 1 millisecond (if `0` is passed, it is automatically replaced
104
- // with `1`) and wants you to use `setImmediate` instead.
105
- if (ms < 1 && typeof setImmediate === "function") {
106
- setImmediate(() => {
107
- if (killedTracked.killed)
108
- return;
109
- try {
110
- instance.exports.timer_finished();
111
- }
112
- catch (_error) { }
113
- });
114
- }
115
- else {
116
- setTimeout(() => {
117
- if (killedTracked.killed)
118
- return;
119
- try {
120
- instance.exports.timer_finished();
121
- }
122
- catch (_error) { }
123
- }, ms);
124
- }
125
- },
126
- // Must create a new connection object. This implementation stores the created object in
127
- // `connections`.
128
- connection_new: (connectionId, addrPtr, addrLen, errorBufferIndexPtr) => {
129
- const instance = config.instance;
130
- addrPtr >>>= 0;
131
- addrLen >>>= 0;
132
- errorBufferIndexPtr >>>= 0;
133
- if (!!connections[connectionId]) {
134
- throw new Error("internal error: connection already allocated");
135
- }
136
- try {
137
- if (killedTracked.killed)
138
- throw new Error("killAll invoked");
139
- const address = buffer.utf8BytesToString(new Uint8Array(instance.exports.memory.buffer), addrPtr, addrLen);
140
- const connec = config.connect({
141
- address,
142
- onOpen: (info) => {
143
- if (killedTracked.killed)
144
- return;
145
- try {
146
- switch (info.type) {
147
- case 'single-stream': {
148
- instance.exports.connection_open_single_stream(connectionId, 0, info.initialWritableBytes, info.writeClosable ? 1 : 0);
149
- break;
150
- }
151
- case 'multi-stream': {
152
- const handshakeTy = new Uint8Array(1 + info.localTlsCertificateMultihash.length + info.remoteTlsCertificateMultihash.length);
153
- buffer.writeUInt8(handshakeTy, 0, 0);
154
- handshakeTy.set(info.localTlsCertificateMultihash, 1);
155
- handshakeTy.set(info.remoteTlsCertificateMultihash, 1 + info.localTlsCertificateMultihash.length);
156
- config.bufferIndices[0] = handshakeTy;
157
- instance.exports.connection_open_multi_stream(connectionId, 0);
158
- delete config.bufferIndices[0];
159
- break;
160
- }
161
- }
162
- }
163
- catch (_error) { }
164
- },
165
- onConnectionReset: (message) => {
166
- if (killedTracked.killed)
167
- return;
168
- try {
169
- config.bufferIndices[0] = new TextEncoder().encode(message);
170
- instance.exports.connection_reset(connectionId, 0);
171
- delete config.bufferIndices[0];
172
- }
173
- catch (_error) { }
174
- },
175
- onWritableBytes: (numExtra, streamId) => {
176
- if (killedTracked.killed)
177
- return;
178
- try {
179
- instance.exports.stream_writable_bytes(connectionId, streamId || 0, numExtra);
180
- }
181
- catch (_error) { }
182
- },
183
- onMessage: (message, streamId) => {
184
- if (killedTracked.killed)
185
- return;
186
- try {
187
- config.bufferIndices[0] = message;
188
- instance.exports.stream_message(connectionId, streamId || 0, 0);
189
- delete config.bufferIndices[0];
190
- }
191
- catch (_error) { }
192
- },
193
- onStreamOpened: (streamId, direction, initialWritableBytes) => {
194
- if (killedTracked.killed)
195
- return;
196
- try {
197
- instance.exports.connection_stream_opened(connectionId, streamId, direction === 'outbound' ? 1 : 0, initialWritableBytes);
198
- }
199
- catch (_error) { }
200
- },
201
- onStreamReset: (streamId) => {
202
- if (killedTracked.killed)
203
- return;
204
- try {
205
- instance.exports.stream_reset(connectionId, streamId);
206
- }
207
- catch (_error) { }
208
- }
209
- });
210
- connections[connectionId] = connec;
211
- return 0;
212
- }
213
- catch (error) {
214
- const isBadAddress = error instanceof ConnectionError;
215
- let errorStr = "Unknown error";
216
- if (error instanceof Error) {
217
- errorStr = error.toString();
218
- }
219
- const mem = new Uint8Array(instance.exports.memory.buffer);
220
- config.bufferIndices[0] = new TextEncoder().encode(errorStr);
221
- buffer.writeUInt32LE(mem, errorBufferIndexPtr, 0);
222
- buffer.writeUInt8(mem, errorBufferIndexPtr + 4, isBadAddress ? 1 : 0);
223
- return 1;
224
- }
225
- },
226
- // Must close and destroy the connection object.
227
- reset_connection: (connectionId) => {
228
- if (killedTracked.killed)
229
- return;
230
- const connection = connections[connectionId];
231
- connection.reset();
232
- delete connections[connectionId];
233
- },
234
- // Opens a new substream on a multi-stream connection.
235
- connection_stream_open: (connectionId) => {
236
- const connection = connections[connectionId];
237
- connection.openOutSubstream();
238
- },
239
- // Closes a substream on a multi-stream connection.
240
- connection_stream_reset: (connectionId, streamId) => {
241
- const connection = connections[connectionId];
242
- connection.reset(streamId);
243
- },
244
- // Must queue the data found in the WebAssembly memory at the given pointer. It is assumed
245
- // that this function is called only when the connection is in an open state.
246
- stream_send: (connectionId, streamId, ptr, len) => {
247
- if (killedTracked.killed)
248
- return;
249
- const instance = config.instance;
250
- ptr >>>= 0;
251
- len >>>= 0;
252
- const data = new Uint8Array(instance.exports.memory.buffer).slice(ptr, ptr + len);
253
- const connection = connections[connectionId];
254
- connection.send(data, streamId); // TODO: docs says the streamId is provided only for multi-stream connections, but here it's always provided
255
- },
256
- stream_send_close: (connectionId, streamId) => {
257
- if (killedTracked.killed)
258
- return;
259
- const connection = connections[connectionId];
260
- connection.closeSend(streamId); // TODO: docs says the streamId is provided only for multi-stream connections, but here it's always provided
261
- },
262
- current_task_entered: (ptr, len) => {
263
- if (killedTracked.killed)
264
- return;
265
- const instance = config.instance;
266
- ptr >>>= 0;
267
- len >>>= 0;
268
- const taskName = buffer.utf8BytesToString(new Uint8Array(instance.exports.memory.buffer), ptr, len);
269
- if (config.currentTaskCallback)
270
- config.currentTaskCallback(taskName);
271
- },
272
- current_task_exit: () => {
273
- if (killedTracked.killed)
274
- return;
275
- if (config.currentTaskCallback)
276
- config.currentTaskCallback(null);
277
- }
278
- };
279
- return { imports, killAll };
280
- }
@@ -1,27 +0,0 @@
1
- import type { SmoldotWasmInstance } from './bindings.js';
2
- export interface Config {
3
- instance?: SmoldotWasmInstance;
4
- /**
5
- * Fills the given buffer with randomly-generated bytes.
6
- */
7
- getRandomValues: (buffer: Uint8Array) => void;
8
- /**
9
- * Returns the number of milliseconds since an arbitrary epoch.
10
- */
11
- performanceNow: () => number;
12
- /**
13
- * List of environment variables to feed to the Rust program. An array of strings.
14
- * Example: `["RUST_BACKTRACE=1", "RUST_LOG=foo"];`
15
- *
16
- * Must never be modified after the bindings have been initialized.
17
- */
18
- envVars: string[];
19
- /**
20
- * Closure to call when the Wasm instance calls `proc_exit`.
21
- *
22
- * This callback will always be invoked from within a binding called the Wasm instance.
23
- */
24
- onProcExit: (retCode: number) => never;
25
- }
26
- declare const _default: (config: Config) => WebAssembly.ModuleImports;
27
- export default _default;
@@ -1,170 +0,0 @@
1
- // Smoldot
2
- // Copyright (C) 2019-2022 Parity Technologies (UK) Ltd.
3
- // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
4
- // This program is free software: you can redistribute it and/or modify
5
- // it under the terms of the GNU General Public License as published by
6
- // the Free Software Foundation, either version 3 of the License, or
7
- // (at your option) any later version.
8
- // This program is distributed in the hope that it will be useful,
9
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
10
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
- // GNU General Public License for more details.
12
- // You should have received a copy of the GNU General Public License
13
- // along with this program. If not, see <http://www.gnu.org/licenses/>.
14
- //! Exports a function that provides bindings for the Wasi interface.
15
- //!
16
- //! These bindings can then be used by the Wasm virtual machine to invoke Wasi-related functions.
17
- //! See <https://wasi.dev/>.
18
- //!
19
- //! In order to use this code, call the function passing an object, then fill the `instance` field
20
- //! of that object with the Wasm instance.
21
- import * as buffer from './buffer.js';
22
- export default (config) => {
23
- // Buffers holding temporary data being written by the Rust code to respectively stdout and
24
- // stderr.
25
- let stdoutBuffer = "";
26
- let stderrBuffer = "";
27
- return {
28
- // Need to fill the buffer described by `ptr` and `len` with random data.
29
- // This data will be used in order to generate secrets. Do not use a dummy implementation!
30
- random_get: (ptr, len) => {
31
- const instance = config.instance;
32
- ptr >>>= 0;
33
- len >>>= 0;
34
- const baseBuffer = new Uint8Array(instance.exports.memory.buffer)
35
- .subarray(ptr, ptr + len);
36
- for (let iter = 0; iter < len; iter += 65536) {
37
- // `baseBuffer.subarray` automatically saturates at the end of the buffer
38
- config.getRandomValues(baseBuffer.subarray(iter, iter + 65536));
39
- }
40
- return 0;
41
- },
42
- clock_time_get: (clockId, _precision, outPtr) => {
43
- // See <https://github.com/rust-lang/rust/blob/master/library/std/src/sys/wasi/time.rs>
44
- // and <docs.rs/wasi/> for help.
45
- const instance = config.instance;
46
- const mem = new Uint8Array(instance.exports.memory.buffer);
47
- outPtr >>>= 0;
48
- // We ignore the precision, as it can't be implemented anyway.
49
- switch (clockId) {
50
- case 0: {
51
- // Realtime clock.
52
- const now = BigInt(Math.floor(Date.now())) * BigInt(1000000);
53
- buffer.writeUInt64LE(mem, outPtr, now);
54
- // Success.
55
- return 0;
56
- }
57
- case 1: {
58
- // Monotonic clock.
59
- const nowMs = config.performanceNow();
60
- const nowMsInt = Math.floor(nowMs);
61
- const now = BigInt(nowMsInt) * BigInt(1000000) +
62
- BigInt(Math.floor(((nowMs - nowMsInt) * 1000000)));
63
- buffer.writeUInt64LE(mem, outPtr, now);
64
- // Success.
65
- return 0;
66
- }
67
- default:
68
- // Return an `EINVAL` error.
69
- return 28;
70
- }
71
- },
72
- // Writing to a file descriptor is used in order to write to stdout/stderr.
73
- fd_write: (fd, addr, num, outPtr) => {
74
- const instance = config.instance;
75
- outPtr >>>= 0;
76
- // Only stdout and stderr are open for writing.
77
- if (fd != 1 && fd != 2) {
78
- return 8;
79
- }
80
- const mem = new Uint8Array(instance.exports.memory.buffer);
81
- // `fd_write` passes a buffer containing itself a list of pointers and lengths to the
82
- // actual buffers. See writev(2).
83
- let toWrite = "";
84
- let totalLength = 0;
85
- for (let i = 0; i < num; i++) {
86
- const buf = buffer.readUInt32LE(mem, addr + 4 * i * 2);
87
- const bufLen = buffer.readUInt32LE(mem, addr + 4 * (i * 2 + 1));
88
- toWrite += buffer.utf8BytesToString(mem, buf, bufLen);
89
- totalLength += bufLen;
90
- }
91
- const flushBuffer = (string) => {
92
- // As documented in the documentation of `println!`, lines are always split by a
93
- // single `\n` in Rust.
94
- while (true) {
95
- const index = string.indexOf('\n');
96
- if (index != -1) {
97
- // Note that it is questionnable to use `console.log` from within a
98
- // library. However this simply reflects the usage of `println!` in the
99
- // Rust code. In other words, it is `println!` that shouldn't be used in
100
- // the first place. The harm of not showing text printed with `println!`
101
- // at all is greater than the harm possibly caused by accidentally leaving
102
- // a `println!` in the code.
103
- console.log(string.substring(0, index));
104
- string = string.substring(index + 1);
105
- }
106
- else {
107
- return string;
108
- }
109
- }
110
- };
111
- // Append the newly-written data to either `stdout_buffer` or `stderr_buffer`, and
112
- // print their content if necessary.
113
- if (fd == 1) {
114
- stdoutBuffer += toWrite;
115
- stdoutBuffer = flushBuffer(stdoutBuffer);
116
- }
117
- else if (fd == 2) {
118
- stderrBuffer += toWrite;
119
- stderrBuffer = flushBuffer(stderrBuffer);
120
- }
121
- // Need to write in `out_ptr` how much data was "written".
122
- buffer.writeUInt32LE(mem, outPtr, totalLength);
123
- return 0;
124
- },
125
- // It's unclear how to properly implement yielding, but a no-op works fine as well.
126
- sched_yield: () => {
127
- return 0;
128
- },
129
- // Used by Rust in catastrophic situations, such as a double panic.
130
- proc_exit: (retCode) => {
131
- config.onProcExit(retCode);
132
- },
133
- // Return the number of environment variables and the total size of all environment
134
- // variables. This is called in order to initialize buffers before `environ_get`.
135
- environ_sizes_get: (argcOut, argvBufSizeOut) => {
136
- const instance = config.instance;
137
- argcOut >>>= 0;
138
- argvBufSizeOut >>>= 0;
139
- let totalLen = 0;
140
- config.envVars.forEach(e => totalLen += new TextEncoder().encode(e).length + 1); // +1 for trailing \0
141
- const mem = new Uint8Array(instance.exports.memory.buffer);
142
- buffer.writeUInt32LE(mem, argcOut, config.envVars.length);
143
- buffer.writeUInt32LE(mem, argvBufSizeOut, totalLen);
144
- return 0;
145
- },
146
- // Write the environment variables to the given pointers.
147
- // `argv` is a pointer to a buffer that must be overwritten with a list of pointers to
148
- // environment variables, and `argvBuf` is a pointer to a buffer where to actually store
149
- // the environment variables.
150
- // The sizes of the buffers were determined by calling `environ_sizes_get`.
151
- environ_get: (argv, argvBuf) => {
152
- const instance = config.instance;
153
- argv >>>= 0;
154
- argvBuf >>>= 0;
155
- const mem = new Uint8Array(instance.exports.memory.buffer);
156
- let argvPos = 0;
157
- let argvBufPos = 0;
158
- config.envVars.forEach(envVar => {
159
- const encoded = new TextEncoder().encode(envVar);
160
- buffer.writeUInt32LE(mem, argv + argvPos, argvBuf + argvBufPos);
161
- argvPos += 4;
162
- mem.set(encoded, argvBuf + argvBufPos);
163
- argvBufPos += encoded.length;
164
- buffer.writeUInt8(mem, argvBuf + argvBufPos, 0);
165
- argvBufPos += 1;
166
- });
167
- return 0;
168
- },
169
- };
170
- };
@@ -1,31 +0,0 @@
1
- /**
2
- * Interface that the Wasm module exports. Contains the functions that are exported by the Rust
3
- * code.
4
- *
5
- * Must match the bindings found in the Rust code.
6
- */
7
- export interface SmoldotWasmExports extends WebAssembly.Exports {
8
- memory: WebAssembly.Memory;
9
- init: (maxLogLevel: number) => void;
10
- advance_execution: () => number;
11
- start_shutdown: () => void;
12
- add_chain: (chainSpecBufferIndex: number, databaseContentBufferIndex: number, jsonRpcRunning: number, potentialRelayChainsBufferIndex: number) => number;
13
- remove_chain: (chainId: number) => void;
14
- chain_is_ok: (chainId: number) => number;
15
- chain_error_len: (chainId: number) => number;
16
- chain_error_ptr: (chainId: number) => number;
17
- json_rpc_send: (textBufferIndex: number, chainId: number) => number;
18
- json_rpc_responses_peek: (chainId: number) => number;
19
- json_rpc_responses_pop: (chainId: number) => void;
20
- timer_finished: () => void;
21
- connection_open_single_stream: (connectionId: number, handshakeTy: number, initialWritableBytes: number, writeClosable: number) => void;
22
- connection_open_multi_stream: (connectionId: number, handshakeTyBufferIndex: number) => void;
23
- stream_writable_bytes: (connectionId: number, streamId: number, numBytes: number) => void;
24
- stream_message: (connectionId: number, streamId: number, bufferIndex: number) => void;
25
- connection_stream_opened: (connectionId: number, streamId: number, outbound: number, initialWritableBytes: number) => void;
26
- connection_reset: (connectionId: number, bufferIndex: number) => void;
27
- stream_reset: (connectionId: number, streamId: number) => void;
28
- }
29
- export interface SmoldotWasmInstance extends WebAssembly.Instance {
30
- readonly exports: SmoldotWasmExports;
31
- }
@@ -1,4 +0,0 @@
1
- // Smoldot
2
- // Copyright (C) 2019-2022 Parity Technologies (UK) Ltd.
3
- // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
4
- export {};
@@ -1,45 +0,0 @@
1
- import * as instance from './raw-instance.js';
2
- export { PlatformBindings, ConnectionError, ConnectionConfig, Connection } from './raw-instance.js';
3
- /**
4
- * Thrown in case the underlying client encounters an unexpected crash.
5
- *
6
- * This is always an internal bug in smoldot and is never supposed to happen.
7
- */
8
- export declare class CrashError extends Error {
9
- constructor(message: string);
10
- }
11
- /**
12
- * Thrown in case a malformed JSON-RPC request is sent.
13
- */
14
- export declare class MalformedJsonRpcError extends Error {
15
- constructor();
16
- }
17
- /**
18
- * Thrown in case the buffer of JSON-RPC requests is full and cannot accept any more request.
19
- */
20
- export declare class QueueFullError extends Error {
21
- constructor();
22
- }
23
- /**
24
- * Contains the configuration of the instance.
25
- */
26
- export interface Config {
27
- wasmModule: Promise<WebAssembly.Module>;
28
- logCallback: (level: number, target: string, message: string) => void;
29
- maxLogLevel: number;
30
- cpuRateLimit: number;
31
- }
32
- export interface Instance {
33
- request: (request: string, chainId: number) => void;
34
- nextJsonRpcResponse: (chainId: number) => Promise<string>;
35
- addChain: (chainSpec: string, databaseContent: string, potentialRelayChains: number[], disableJsonRpc: boolean) => Promise<{
36
- success: true;
37
- chainId: number;
38
- } | {
39
- success: false;
40
- error: string;
41
- }>;
42
- removeChain: (chainId: number) => void;
43
- startShutdown: () => void;
44
- }
45
- export declare function start(configMessage: Config, platformBindings: instance.PlatformBindings): Instance;