@hazae41/bobine 0.0.11 → 0.0.13
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 +7 -112
- package/out/libs/packed/mod.d.ts +13 -0
- package/out/libs/packed/mod.js +114 -0
- package/out/mods/helper/bin.js +2 -2
- package/out/mods/server/mod.js +6 -3
- package/out/mods/worker/bin.js +17 -26
- package/package.json +1 -1
- package/out/libs/packs/mod.d.ts +0 -13
- package/out/libs/packs/mod.js +0 -139
package/README.md
CHANGED
|
@@ -132,150 +132,45 @@ declare function add(x: externref, y: externref): externref
|
|
|
132
132
|
|
|
133
133
|
You can pass bytes between modules by storing them in the blob storage and loading them via reference
|
|
134
134
|
|
|
135
|
-
- `blobs.save(offset: i32, length: i32): blobref` = save `length` bytes at `offset` of your memory to the blob storage
|
|
136
|
-
|
|
137
|
-
- `blobs.load(blob: blobref, offset: i32): void` = load some blob into your memory at `offset`
|
|
138
|
-
|
|
139
|
-
- `blobs.equals(left: blobref, right: blobref): bool` = check if two blobs are equals without loading them into memory
|
|
140
|
-
|
|
141
|
-
- `blobs.concat(left: blobref, right: blobref): blobref` = concatenate two blobs without loading them into memory
|
|
142
|
-
|
|
143
|
-
- `blob.to_hex/from_hex/to_base64/from_base64(blob: blobref): blobref` = convert blobs to/from hex/base64 without loading them into memory
|
|
144
|
-
|
|
145
135
|
#### BigInts module
|
|
146
136
|
|
|
147
|
-
You can work with infinite-precision bigints
|
|
148
|
-
|
|
149
|
-
- `bigints.add(left: bigintref, right: bigintref): bigintref` = add two bigints
|
|
150
|
-
|
|
151
|
-
- `bigints.sub(left: bigintref, right: bigintref): bigintref` = subtract two bigints
|
|
152
|
-
|
|
153
|
-
- `bigints.mul(left: bigintref, right: bigintref): bigintref` = multiply two bigints
|
|
154
|
-
|
|
155
|
-
- `bigints.div(left: bigintref, right: bigintref): bigintref` = divide two bigints
|
|
137
|
+
You can work with infinite-precision bigints and convert them with blobs and texts
|
|
156
138
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
- `bigints.encode(bigint: bigintref): blobref` = convert bigint to bytes
|
|
160
|
-
|
|
161
|
-
- `bigints.decode(base16: blobref): bigintref` = convert bytes to bigint
|
|
162
|
-
|
|
163
|
-
- `bigints.to_base16(bigint: bigintref): blobref` = convert bigint to hex utf8 bytes
|
|
164
|
-
|
|
165
|
-
- `bigints.from_base16(base16: blobref): bigintref` = convert hex utf8 bytes to bigint
|
|
166
|
-
|
|
167
|
-
- `bigints.to_base10(bigint: bigintref): blobref` = convert bigint to base10 utf8 bytes
|
|
168
|
-
|
|
169
|
-
- `bigints.from_base10(base16: blobref): bigintref` = convert base10 utf8 bytes to bigint
|
|
139
|
+
And many others
|
|
170
140
|
|
|
171
141
|
#### Packs module
|
|
172
142
|
|
|
173
143
|
You can pack various arguments (numbers, refs) into a pack which can be passed between modules and/or encoded/decoded into bytes
|
|
174
144
|
|
|
175
|
-
- `packs.create(...values: any[]): packref` = create a new pack from the provided values (number, blobref, packref, null)
|
|
176
|
-
|
|
177
|
-
- `packs.encode(pack: packref): blobref` = encodes values into bytes using the following pseudocode
|
|
178
|
-
|
|
179
|
-
```tsx
|
|
180
|
-
function writePack(pack: packref) {
|
|
181
|
-
for (const value of values) {
|
|
182
|
-
if (isNull(value)) {
|
|
183
|
-
writeUint8(1)
|
|
184
|
-
continue
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
if (isNumber(value)) {
|
|
188
|
-
writeUint8(2)
|
|
189
|
-
writeFloat64(value, "little-endian")
|
|
190
|
-
continue
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
if (isBigInt(value)) {
|
|
194
|
-
writeUint8(3)
|
|
195
|
-
writeUint32(value.toHex().length, "little-endian")
|
|
196
|
-
writeBytes(value.toHex())
|
|
197
|
-
continue
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
if (isBlobref(value)) {
|
|
201
|
-
writeUint8(4)
|
|
202
|
-
writeUint32(value.length, "little-endian")
|
|
203
|
-
writeBytes(value)
|
|
204
|
-
continue
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
if (isPackref(value)) {
|
|
208
|
-
writeUint8(5)
|
|
209
|
-
writePack(value)
|
|
210
|
-
continue
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
throw new Error()
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
writeUint8(0)
|
|
217
|
-
}
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
- `packs.decode(blob: blobref): packref` = decodes bytes into a pack of values using the same pseudocode but for reading
|
|
221
|
-
|
|
222
|
-
- `packs.concat(left: packref, right: packref)` = concatenate two packs into one (basically does `[...left, ...right]`)
|
|
223
|
-
|
|
224
|
-
- `packs.get<T>(pack: packref, index: i32): T` = get the value of a pack at `index` (throws if not found)
|
|
225
|
-
|
|
226
|
-
- `packs.length(pack: packref): i32` = get the length of a pack
|
|
227
|
-
|
|
228
145
|
#### Environment module
|
|
229
146
|
|
|
230
147
|
Get infos about the executing environment
|
|
231
148
|
|
|
232
|
-
- `env.mode: i32` = `1` if execution, `2` is simulation
|
|
233
|
-
|
|
234
|
-
- `env.uuid(): blobref` = get the unique uuid of this environment (similar to a chain id)
|
|
235
|
-
|
|
236
149
|
#### Modules module
|
|
237
150
|
|
|
238
151
|
Modules are identified by their address as a blob of bytes (pure sha256-output 32-length bytes without any encoding)
|
|
239
152
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
- `modules.call(module: blobref, method: blobref, params: packref): packref` = dynamically call a module method with the given params as pack and return value as a 1-length pack
|
|
243
|
-
|
|
244
|
-
- `modules.create(code: blobref, salt: blobref): blobref` = dynamically create a new module with the given code and salt, returns the module address
|
|
245
|
-
|
|
246
|
-
- `modules.self(): blobref` = get your module address as blob
|
|
153
|
+
You can dynamically create modules, call modules, get their bytecode
|
|
247
154
|
|
|
248
155
|
#### Storage module
|
|
249
156
|
|
|
250
|
-
You can use a private storage (it works like storage and events at the same time)
|
|
251
|
-
|
|
252
|
-
- `storage.set(key: blobref, value: blobref): void` = set some value to storage at key
|
|
253
|
-
|
|
254
|
-
- `storage.get(key: blobref): blobref` = get the latest value from storage at key
|
|
157
|
+
You can use a private key-value storage (it works like storage and events at the same time)
|
|
255
158
|
|
|
256
159
|
#### SHA-256 module
|
|
257
160
|
|
|
258
161
|
Use the SHA-256 hashing algorithm
|
|
259
162
|
|
|
260
|
-
- `sha256.digest(payload: blobref): blobref` = hash the payload and returns the digest
|
|
261
|
-
|
|
262
163
|
#### Ed25519 module
|
|
263
164
|
|
|
264
|
-
Use the Ed25519 signing algorithm
|
|
265
|
-
|
|
266
|
-
- `ed25519.verify(pubkey: blobref, signature: blobref, payload: blobref): boolean` = verify a signature
|
|
267
|
-
|
|
268
|
-
- `ed25519.sign(payload: blobref): blobref` = (experimental) sign payload using the miner's private key
|
|
165
|
+
Use the Ed25519 signing algorithm to verify any signature and (experimentally) sign payload using the miner's private key
|
|
269
166
|
|
|
270
167
|
#### Symbols module (experimental)
|
|
271
168
|
|
|
272
|
-
|
|
169
|
+
Create unique references that can be passed around
|
|
273
170
|
|
|
274
171
|
#### References module (experimental)
|
|
275
172
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
- `refs.denumerize(pointer: i32): symbolref/blobref/packref` = get the exact same reference back from your private pointer
|
|
173
|
+
Translate any reference into a unique private pointer that can be stored into data structures
|
|
279
174
|
|
|
280
175
|
This can be useful if you want to check a reference for authenticity
|
|
281
176
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Cursor } from "@hazae41/cursor";
|
|
2
|
+
export type Packable = null | number | Uint8Array | string | bigint | Array<Packable>;
|
|
3
|
+
export declare class Packed {
|
|
4
|
+
readonly value: Packable;
|
|
5
|
+
constructor(value: Packable);
|
|
6
|
+
sizeOrThrow(): number;
|
|
7
|
+
writeOrThrow(cursor: Cursor): void;
|
|
8
|
+
}
|
|
9
|
+
export declare namespace Packed {
|
|
10
|
+
function readOrThrow(cursor: Cursor): Packable;
|
|
11
|
+
function sizeOrThrow(value: Packable): number;
|
|
12
|
+
function writeOrThrow(value: Packable, cursor: Cursor): void;
|
|
13
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
// deno-lint-ignore-file no-namespace
|
|
2
|
+
export class Packed {
|
|
3
|
+
value;
|
|
4
|
+
constructor(value) {
|
|
5
|
+
this.value = value;
|
|
6
|
+
}
|
|
7
|
+
sizeOrThrow() {
|
|
8
|
+
return Packed.sizeOrThrow(this.value);
|
|
9
|
+
}
|
|
10
|
+
writeOrThrow(cursor) {
|
|
11
|
+
Packed.writeOrThrow(this.value, cursor);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
(function (Packed) {
|
|
15
|
+
function readOrThrow(cursor) {
|
|
16
|
+
const type = cursor.readUint8OrThrow();
|
|
17
|
+
if (type === 0)
|
|
18
|
+
return null;
|
|
19
|
+
if (type === 1)
|
|
20
|
+
return cursor.readFloat64OrThrow(true);
|
|
21
|
+
if (type === 2)
|
|
22
|
+
return cursor.readOrThrow(cursor.readUint32OrThrow(true));
|
|
23
|
+
if (type === 3) {
|
|
24
|
+
const size = cursor.readUint32OrThrow(true);
|
|
25
|
+
const data = cursor.readOrThrow(size);
|
|
26
|
+
return new TextDecoder().decode(data);
|
|
27
|
+
}
|
|
28
|
+
if (type === 4) {
|
|
29
|
+
const negative = cursor.readUint8OrThrow();
|
|
30
|
+
const size = cursor.readUint32OrThrow(true);
|
|
31
|
+
const data = cursor.readOrThrow(size);
|
|
32
|
+
const absolute = BigInt("0x" + data.toHex());
|
|
33
|
+
return negative ? -absolute : absolute;
|
|
34
|
+
}
|
|
35
|
+
if (type === 5) {
|
|
36
|
+
const length = cursor.readUint32OrThrow(true);
|
|
37
|
+
const values = new Array(length);
|
|
38
|
+
for (let i = 0; i < length; i++)
|
|
39
|
+
values[i] = readOrThrow(cursor);
|
|
40
|
+
return values;
|
|
41
|
+
}
|
|
42
|
+
throw new Error("Unknown pack type");
|
|
43
|
+
}
|
|
44
|
+
Packed.readOrThrow = readOrThrow;
|
|
45
|
+
function sizeOrThrow(value) {
|
|
46
|
+
if (value == null)
|
|
47
|
+
return 1;
|
|
48
|
+
if (typeof value === "number")
|
|
49
|
+
return 1 + 4;
|
|
50
|
+
if (value instanceof Uint8Array)
|
|
51
|
+
return 1 + 4 + value.length;
|
|
52
|
+
if (typeof value === "string")
|
|
53
|
+
return 1 + 4 + new TextEncoder().encode(value).length;
|
|
54
|
+
if (typeof value === "bigint") {
|
|
55
|
+
const absolute = value < 0n ? -value : value;
|
|
56
|
+
const text = absolute.toString(16);
|
|
57
|
+
const data = Uint8Array.fromHex(text.length % 2 === 1 ? "0" + text : text);
|
|
58
|
+
return 1 + 1 + 4 + data.length;
|
|
59
|
+
}
|
|
60
|
+
if (Array.isArray(value)) {
|
|
61
|
+
let size = 0;
|
|
62
|
+
size += 1;
|
|
63
|
+
size += 4;
|
|
64
|
+
for (const subvalue of value)
|
|
65
|
+
size += sizeOrThrow(subvalue);
|
|
66
|
+
return size;
|
|
67
|
+
}
|
|
68
|
+
throw new Error("Unknown pack value");
|
|
69
|
+
}
|
|
70
|
+
Packed.sizeOrThrow = sizeOrThrow;
|
|
71
|
+
function writeOrThrow(value, cursor) {
|
|
72
|
+
if (value == null) {
|
|
73
|
+
cursor.writeUint8OrThrow(0);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
if (typeof value === "number") {
|
|
77
|
+
cursor.writeUint8OrThrow(1);
|
|
78
|
+
cursor.writeFloat64OrThrow(value, true);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
if (value instanceof Uint8Array) {
|
|
82
|
+
cursor.writeUint8OrThrow(2);
|
|
83
|
+
cursor.writeUint32OrThrow(value.length, true);
|
|
84
|
+
cursor.writeOrThrow(value);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
if (typeof value === "string") {
|
|
88
|
+
cursor.writeUint8OrThrow(3);
|
|
89
|
+
const data = new TextEncoder().encode(value);
|
|
90
|
+
cursor.writeUint32OrThrow(data.length, true);
|
|
91
|
+
cursor.writeOrThrow(data);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
if (typeof value === "bigint") {
|
|
95
|
+
cursor.writeUint8OrThrow(4);
|
|
96
|
+
const [negative, absolute] = value < 0n ? [1, -value] : [0, value];
|
|
97
|
+
const text = absolute.toString(16);
|
|
98
|
+
const data = Uint8Array.fromHex(text.length % 2 === 1 ? "0" + text : text);
|
|
99
|
+
cursor.writeUint8OrThrow(negative);
|
|
100
|
+
cursor.writeUint32OrThrow(data.length, true);
|
|
101
|
+
cursor.writeOrThrow(data);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
if (Array.isArray(value)) {
|
|
105
|
+
cursor.writeUint8OrThrow(5);
|
|
106
|
+
cursor.writeUint32OrThrow(value.length, true);
|
|
107
|
+
for (const subvalue of value)
|
|
108
|
+
writeOrThrow(subvalue, cursor);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
throw new Error("Unknown pack value");
|
|
112
|
+
}
|
|
113
|
+
Packed.writeOrThrow = writeOrThrow;
|
|
114
|
+
})(Packed || (Packed = {}));
|
package/out/mods/helper/bin.js
CHANGED
|
@@ -10,10 +10,10 @@ self.addEventListener("message", async (event) => {
|
|
|
10
10
|
const request = event.data;
|
|
11
11
|
if (request.method === "storage_set") {
|
|
12
12
|
return await runAsImmediateOrThrow(database, async (database) => {
|
|
13
|
-
const [module, method, args,
|
|
13
|
+
const [module, method, args, writes] = event.data.params;
|
|
14
14
|
const moment = await database.prepare(`INSERT INTO moments (epoch, module, method, params) VALUES (0, ?, ?, ?);`).run(module, method, args);
|
|
15
15
|
const writer = database.prepare(`INSERT INTO events (moment, module, key, value) VALUES (?, ?, ?, ?);`);
|
|
16
|
-
for (const [module, key, value] of
|
|
16
|
+
for (const [module, key, value] of writes)
|
|
17
17
|
await writer.run(moment.lastInsertRowid, module, key, value);
|
|
18
18
|
request.result[0] = 1;
|
|
19
19
|
request.result[1] = moment.lastInsertRowid;
|
package/out/mods/server/mod.js
CHANGED
|
@@ -58,7 +58,7 @@ import { connect } from "@tursodatabase/database";
|
|
|
58
58
|
import { existsSync, mkdirSync, symlinkSync, writeFileSync } from "node:fs";
|
|
59
59
|
import { dirname } from "node:path";
|
|
60
60
|
import process from "node:process";
|
|
61
|
-
import {
|
|
61
|
+
import { Packed } from "../../libs/packed/mod.js";
|
|
62
62
|
export async function serveWithEnv(prefix = "") {
|
|
63
63
|
const { DATABASE_PATH = process.env[prefix + "DATABASE_PATH"], SCRIPTS_PATH = process.env[prefix + "SCRIPTS_PATH"], ED25519_PRIVATE_KEY_HEX = process.env[prefix + "ED25519_PRIVATE_KEY_HEX"], ED25519_PUBLIC_KEY_HEX = process.env[prefix + "ED25519_PUBLIC_KEY_HEX"], } = {};
|
|
64
64
|
if (DATABASE_PATH == null)
|
|
@@ -92,7 +92,8 @@ export async function serve(config) {
|
|
|
92
92
|
|
|
93
93
|
module TEXT NOT NULL,
|
|
94
94
|
|
|
95
|
-
key
|
|
95
|
+
key TEXT NOT NULL,
|
|
96
|
+
|
|
96
97
|
value BLOB NOT NULL
|
|
97
98
|
);`);
|
|
98
99
|
await database.exec(`CREATE TABLE IF NOT EXISTS moments (
|
|
@@ -101,7 +102,9 @@ export async function serve(config) {
|
|
|
101
102
|
epoch INTEGER NOT NULL,
|
|
102
103
|
|
|
103
104
|
module TEXT NOT NULL,
|
|
105
|
+
|
|
104
106
|
method TEXT NOT NULL,
|
|
107
|
+
|
|
105
108
|
params BLOB NOT NULL
|
|
106
109
|
);`);
|
|
107
110
|
await database.close();
|
|
@@ -141,7 +144,7 @@ export async function serve(config) {
|
|
|
141
144
|
const sparksAsBigInt = (2n ** 256n) / BigInt("0x" + new Uint8Array(await crypto.subtle.digest("SHA-256", effortAsBytes)).toHex());
|
|
142
145
|
if (sparksAsBigInt < (wasmAsBytes.length + saltAsBytes.length))
|
|
143
146
|
return Response.json(null, { status: 402 });
|
|
144
|
-
const packAsBytes = Writable.writeToBytesOrThrow(new
|
|
147
|
+
const packAsBytes = Writable.writeToBytesOrThrow(new Packed([wasmAsBytes, saltAsBytes]));
|
|
145
148
|
const digestOfWasmAsBytes = new Uint8Array(await crypto.subtle.digest("SHA-256", wasmAsBytes));
|
|
146
149
|
const digestOfPackAsBytes = new Uint8Array(await crypto.subtle.digest("SHA-256", packAsBytes));
|
|
147
150
|
const digestOfWasmAsHex = digestOfWasmAsBytes.toHex();
|
package/out/mods/worker/bin.js
CHANGED
|
@@ -5,21 +5,21 @@ import * as Wasm from "@hazae41/wasm";
|
|
|
5
5
|
import { Buffer } from "node:buffer";
|
|
6
6
|
import { existsSync, readFileSync, symlinkSync, writeFileSync } from "node:fs";
|
|
7
7
|
import { meter } from "../../libs/metering/mod.js";
|
|
8
|
-
import {
|
|
8
|
+
import { Packed } from "../../libs/packed/mod.js";
|
|
9
9
|
const config = await fetch(self.name).then(res => res.json());
|
|
10
10
|
const helper = new Worker(import.meta.resolve("../helper/bin.js"), { name: self.name, type: "module" });
|
|
11
11
|
function run(module, method, params, mode, maxsparks) {
|
|
12
12
|
let sparks = 0n;
|
|
13
13
|
const exports = {};
|
|
14
|
-
const caches = new Map();
|
|
15
14
|
const logs = new Array();
|
|
15
|
+
const caches = new Map();
|
|
16
16
|
const reads = new Array();
|
|
17
17
|
const writes = new Array();
|
|
18
|
-
const pack_encode = (
|
|
19
|
-
return Writable.writeToBytesOrThrow(new
|
|
18
|
+
const pack_encode = (value) => {
|
|
19
|
+
return Writable.writeToBytesOrThrow(new Packed(value));
|
|
20
20
|
};
|
|
21
21
|
const pack_decode = (bytes) => {
|
|
22
|
-
return Readable.readFromBytesOrThrow(
|
|
22
|
+
return Readable.readFromBytesOrThrow(Packed, bytes);
|
|
23
23
|
};
|
|
24
24
|
const sparks_consume = (amount) => {
|
|
25
25
|
sparks += amount;
|
|
@@ -173,12 +173,6 @@ function run(module, method, params, mode, maxsparks) {
|
|
|
173
173
|
if (value === undefined)
|
|
174
174
|
throw new Error("Not found");
|
|
175
175
|
return value;
|
|
176
|
-
},
|
|
177
|
-
encode: (pack) => {
|
|
178
|
-
return pack_encode(pack);
|
|
179
|
-
},
|
|
180
|
-
decode: (blob) => {
|
|
181
|
-
return pack_decode(blob);
|
|
182
176
|
}
|
|
183
177
|
};
|
|
184
178
|
imports["bigints"] = {
|
|
@@ -239,14 +233,6 @@ function run(module, method, params, mode, maxsparks) {
|
|
|
239
233
|
pow: (left, right) => {
|
|
240
234
|
return left ** right;
|
|
241
235
|
},
|
|
242
|
-
encode: (bigint) => {
|
|
243
|
-
const text = bigint.toString(16);
|
|
244
|
-
const data = Uint8Array.fromHex(text.length % 2 === 1 ? "0" + text : text);
|
|
245
|
-
return data;
|
|
246
|
-
},
|
|
247
|
-
decode: (bytes) => {
|
|
248
|
-
return BigInt("0x" + bytes.toHex());
|
|
249
|
-
},
|
|
250
236
|
from_base16: (text) => {
|
|
251
237
|
return BigInt("0x" + text);
|
|
252
238
|
},
|
|
@@ -280,7 +266,7 @@ function run(module, method, params, mode, maxsparks) {
|
|
|
280
266
|
load(moduleAsString);
|
|
281
267
|
if (typeof exports[moduleAsString][methodAsString] !== "function")
|
|
282
268
|
throw new Error("Not found");
|
|
283
|
-
return
|
|
269
|
+
return exports[moduleAsString][methodAsString](...paramsAsPack);
|
|
284
270
|
},
|
|
285
271
|
load: (moduleAsBytes) => {
|
|
286
272
|
return readFileSync(`${config.scripts.path}/${moduleAsBytes.toHex()}.wasm`);
|
|
@@ -290,9 +276,10 @@ function run(module, method, params, mode, maxsparks) {
|
|
|
290
276
|
}
|
|
291
277
|
};
|
|
292
278
|
imports["storage"] = {
|
|
293
|
-
set: (key,
|
|
279
|
+
set: (key, fresh) => {
|
|
294
280
|
const cache = caches.get(module);
|
|
295
|
-
cache.set(key,
|
|
281
|
+
cache.set(key, fresh);
|
|
282
|
+
const value = pack_encode(fresh);
|
|
296
283
|
writes.push([module, key, value]);
|
|
297
284
|
return;
|
|
298
285
|
},
|
|
@@ -309,9 +296,10 @@ function run(module, method, params, mode, maxsparks) {
|
|
|
309
296
|
throw new Error("Internal error");
|
|
310
297
|
if (result[1] === 2)
|
|
311
298
|
return null;
|
|
312
|
-
const
|
|
299
|
+
const value = new Uint8Array(result.buffer, 4 + 4 + 4, result[2]).slice();
|
|
300
|
+
const fresh = pack_decode(value);
|
|
313
301
|
cache.set(key, fresh);
|
|
314
|
-
reads.push([module, key,
|
|
302
|
+
reads.push([module, key, value]);
|
|
315
303
|
return fresh;
|
|
316
304
|
}
|
|
317
305
|
};
|
|
@@ -385,8 +373,11 @@ function run(module, method, params, mode, maxsparks) {
|
|
|
385
373
|
const { instance } = load(module);
|
|
386
374
|
if (typeof instance.exports[method] !== "function")
|
|
387
375
|
throw new Error("Not found");
|
|
388
|
-
const
|
|
389
|
-
if (
|
|
376
|
+
const args = pack_decode(params);
|
|
377
|
+
if (!Array.isArray(args))
|
|
378
|
+
throw new Error("Params is not an array");
|
|
379
|
+
const returned = instance.exports[method](...args);
|
|
380
|
+
if (mode !== 1)
|
|
390
381
|
return pack_encode([logs, reads, writes, returned, sparks]);
|
|
391
382
|
if (writes.length) {
|
|
392
383
|
const result = new Int32Array(new SharedArrayBuffer(4 + 4));
|
package/package.json
CHANGED
package/out/libs/packs/mod.d.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { Cursor } from "@hazae41/cursor";
|
|
2
|
-
export declare class Pack {
|
|
3
|
-
readonly values: Array<Pack.Value>;
|
|
4
|
-
constructor(values: Array<Pack.Value>);
|
|
5
|
-
sizeOrThrow(): number;
|
|
6
|
-
writeOrThrow(cursor: Cursor): void;
|
|
7
|
-
}
|
|
8
|
-
export declare namespace Pack {
|
|
9
|
-
type Value = null | number | Uint8Array | string | bigint | Array<Value>;
|
|
10
|
-
function readOrThrow(cursor: Cursor): Array<Value>;
|
|
11
|
-
function sizeOrThrow(values: Array<Value>): number;
|
|
12
|
-
function writeOrThrow(values: Array<Value>, cursor: Cursor): void;
|
|
13
|
-
}
|
package/out/libs/packs/mod.js
DELETED
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
// deno-lint-ignore-file no-namespace
|
|
2
|
-
export class Pack {
|
|
3
|
-
values;
|
|
4
|
-
constructor(values) {
|
|
5
|
-
this.values = values;
|
|
6
|
-
}
|
|
7
|
-
sizeOrThrow() {
|
|
8
|
-
return Pack.sizeOrThrow(this.values);
|
|
9
|
-
}
|
|
10
|
-
writeOrThrow(cursor) {
|
|
11
|
-
Pack.writeOrThrow(this.values, cursor);
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
(function (Pack) {
|
|
15
|
-
function readOrThrow(cursor) {
|
|
16
|
-
const values = [];
|
|
17
|
-
while (true) {
|
|
18
|
-
const type = cursor.readUint8OrThrow();
|
|
19
|
-
if (type === 0)
|
|
20
|
-
break;
|
|
21
|
-
if (type === 1) {
|
|
22
|
-
values.push(null);
|
|
23
|
-
continue;
|
|
24
|
-
}
|
|
25
|
-
if (type === 2) {
|
|
26
|
-
values.push(Pack.readOrThrow(cursor));
|
|
27
|
-
continue;
|
|
28
|
-
}
|
|
29
|
-
if (type === 3) {
|
|
30
|
-
values.push(cursor.readFloat64OrThrow(true));
|
|
31
|
-
continue;
|
|
32
|
-
}
|
|
33
|
-
if (type === 4) {
|
|
34
|
-
const size = cursor.readUint32OrThrow(true);
|
|
35
|
-
values.push(cursor.readOrThrow(size));
|
|
36
|
-
continue;
|
|
37
|
-
}
|
|
38
|
-
if (type === 5) {
|
|
39
|
-
const size = cursor.readUint32OrThrow(true);
|
|
40
|
-
const data = cursor.readOrThrow(size);
|
|
41
|
-
values.push(new TextDecoder().decode(data));
|
|
42
|
-
continue;
|
|
43
|
-
}
|
|
44
|
-
if (type === 6) {
|
|
45
|
-
const negative = cursor.readUint8OrThrow();
|
|
46
|
-
const size = cursor.readUint32OrThrow(true);
|
|
47
|
-
const data = cursor.readOrThrow(size);
|
|
48
|
-
const absolute = BigInt("0x" + data.toHex());
|
|
49
|
-
values.push(negative ? -absolute : absolute);
|
|
50
|
-
continue;
|
|
51
|
-
}
|
|
52
|
-
throw new Error("Unknown pack type");
|
|
53
|
-
}
|
|
54
|
-
return values;
|
|
55
|
-
}
|
|
56
|
-
Pack.readOrThrow = readOrThrow;
|
|
57
|
-
function sizeOrThrow(values) {
|
|
58
|
-
let size = 0;
|
|
59
|
-
for (const value of values) {
|
|
60
|
-
if (value == null) {
|
|
61
|
-
size += 1;
|
|
62
|
-
continue;
|
|
63
|
-
}
|
|
64
|
-
if (Array.isArray(value)) {
|
|
65
|
-
size += 1 + sizeOrThrow(value);
|
|
66
|
-
continue;
|
|
67
|
-
}
|
|
68
|
-
if (typeof value === "number") {
|
|
69
|
-
size += 1 + 4;
|
|
70
|
-
continue;
|
|
71
|
-
}
|
|
72
|
-
if (value instanceof Uint8Array) {
|
|
73
|
-
size += 1 + 4 + value.length;
|
|
74
|
-
continue;
|
|
75
|
-
}
|
|
76
|
-
if (typeof value === "string") {
|
|
77
|
-
const data = new TextEncoder().encode(value);
|
|
78
|
-
size += 1 + 4 + data.length;
|
|
79
|
-
continue;
|
|
80
|
-
}
|
|
81
|
-
if (typeof value === "bigint") {
|
|
82
|
-
const absolute = value < 0n ? -value : value;
|
|
83
|
-
const text = absolute.toString(16);
|
|
84
|
-
const data = Uint8Array.fromHex(text.length % 2 === 1 ? "0" + text : text);
|
|
85
|
-
size += 1 + 1 + 4 + data.length;
|
|
86
|
-
continue;
|
|
87
|
-
}
|
|
88
|
-
throw new Error("Unknown pack value");
|
|
89
|
-
}
|
|
90
|
-
size += 1;
|
|
91
|
-
return size;
|
|
92
|
-
}
|
|
93
|
-
Pack.sizeOrThrow = sizeOrThrow;
|
|
94
|
-
function writeOrThrow(values, cursor) {
|
|
95
|
-
for (const value of values) {
|
|
96
|
-
if (value == null) {
|
|
97
|
-
cursor.writeUint8OrThrow(1);
|
|
98
|
-
continue;
|
|
99
|
-
}
|
|
100
|
-
if (Array.isArray(value)) {
|
|
101
|
-
cursor.writeUint8OrThrow(2);
|
|
102
|
-
writeOrThrow(value, cursor);
|
|
103
|
-
continue;
|
|
104
|
-
}
|
|
105
|
-
if (typeof value === "number") {
|
|
106
|
-
cursor.writeUint8OrThrow(3);
|
|
107
|
-
cursor.writeFloat64OrThrow(value, true);
|
|
108
|
-
continue;
|
|
109
|
-
}
|
|
110
|
-
if (value instanceof Uint8Array) {
|
|
111
|
-
cursor.writeUint8OrThrow(4);
|
|
112
|
-
cursor.writeUint32OrThrow(value.length, true);
|
|
113
|
-
cursor.writeOrThrow(value);
|
|
114
|
-
continue;
|
|
115
|
-
}
|
|
116
|
-
if (typeof value === "string") {
|
|
117
|
-
cursor.writeUint8OrThrow(5);
|
|
118
|
-
const data = new TextEncoder().encode(value);
|
|
119
|
-
cursor.writeUint32OrThrow(data.length, true);
|
|
120
|
-
cursor.writeOrThrow(data);
|
|
121
|
-
continue;
|
|
122
|
-
}
|
|
123
|
-
if (typeof value === "bigint") {
|
|
124
|
-
cursor.writeUint8OrThrow(6);
|
|
125
|
-
const [negative, absolute] = value < 0n ? [1, -value] : [0, value];
|
|
126
|
-
const text = absolute.toString(16);
|
|
127
|
-
const data = Uint8Array.fromHex(text.length % 2 === 1 ? "0" + text : text);
|
|
128
|
-
cursor.writeUint8OrThrow(negative);
|
|
129
|
-
cursor.writeUint32OrThrow(data.length, true);
|
|
130
|
-
cursor.writeOrThrow(data);
|
|
131
|
-
continue;
|
|
132
|
-
}
|
|
133
|
-
throw new Error("Unknown pack value");
|
|
134
|
-
}
|
|
135
|
-
cursor.writeUint8OrThrow(0);
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
Pack.writeOrThrow = writeOrThrow;
|
|
139
|
-
})(Pack || (Pack = {}));
|