@hazae41/bobine 0.0.12 → 0.0.17
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 +2 -4
- package/out/libs/packed/mod.d.ts +13 -0
- package/out/libs/packed/mod.js +114 -0
- package/out/mods/helper/bin.js +3 -2
- package/out/mods/server/bin.js +1 -0
- package/out/mods/server/mod.js +5 -2
- package/out/mods/worker/bin.js +21 -17
- package/package.json +1 -3
- package/out/libs/packs/mod.d.ts +0 -13
- package/out/libs/packs/mod.js +0 -139
package/README.md
CHANGED
|
@@ -2,9 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
A blockchain in your garage
|
|
4
4
|
|
|
5
|
-
https://bobine.tech/
|
|
6
|
-
|
|
7
|
-
[**📦 NPM**](https://www.npmjs.com/package/@hazae41/bobine) • [**📦 JSR**](https://jsr.io/@hazae41/bobine)
|
|
5
|
+
[**🌐 Website**](https://bobine.tech/) • [**📦 NPM**](https://www.npmjs.com/package/@hazae41/bobine)
|
|
8
6
|
|
|
9
7
|
## Features
|
|
10
8
|
|
|
@@ -24,7 +22,7 @@ https://bobine.tech/
|
|
|
24
22
|
Install the binary with Deno
|
|
25
23
|
|
|
26
24
|
```bash
|
|
27
|
-
deno install -gf -A
|
|
25
|
+
deno install -gf -A npm:@hazae41/bobine
|
|
28
26
|
```
|
|
29
27
|
|
|
30
28
|
Generate an Ed25519 keypair by running the following code in your browser/deno/node/bun console
|
|
@@ -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
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/// <reference lib="webworker" />
|
|
1
2
|
import { RpcMethodNotFoundError } from "@hazae41/jsonrpc";
|
|
2
3
|
import { connect } from "@tursodatabase/database";
|
|
3
4
|
import { runAsImmediateOrThrow } from "../../libs/sql/mod.js";
|
|
@@ -10,10 +11,10 @@ self.addEventListener("message", async (event) => {
|
|
|
10
11
|
const request = event.data;
|
|
11
12
|
if (request.method === "storage_set") {
|
|
12
13
|
return await runAsImmediateOrThrow(database, async (database) => {
|
|
13
|
-
const [module, method, args,
|
|
14
|
+
const [module, method, args, writes] = event.data.params;
|
|
14
15
|
const moment = await database.prepare(`INSERT INTO moments (epoch, module, method, params) VALUES (0, ?, ?, ?);`).run(module, method, args);
|
|
15
16
|
const writer = database.prepare(`INSERT INTO events (moment, module, key, value) VALUES (?, ?, ?, ?);`);
|
|
16
|
-
for (const [module, key, value] of
|
|
17
|
+
for (const [module, key, value] of writes)
|
|
17
18
|
await writer.run(moment.lastInsertRowid, module, key, value);
|
|
18
19
|
request.result[0] = 1;
|
|
19
20
|
request.result[1] = moment.lastInsertRowid;
|
package/out/mods/server/bin.js
CHANGED
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)
|
|
@@ -93,6 +93,7 @@ export async function serve(config) {
|
|
|
93
93
|
module TEXT NOT NULL,
|
|
94
94
|
|
|
95
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
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
// deno-lint-ignore-file no-explicit-any no-unused-vars ban-unused-ignore
|
|
2
|
+
/// <reference lib="webworker" />
|
|
2
3
|
import { Readable, Writable } from "@hazae41/binary";
|
|
3
4
|
import { RpcErr, RpcError, RpcMethodNotFoundError, RpcOk } from "@hazae41/jsonrpc";
|
|
4
5
|
import * as Wasm from "@hazae41/wasm";
|
|
5
6
|
import { Buffer } from "node:buffer";
|
|
6
7
|
import { existsSync, readFileSync, symlinkSync, writeFileSync } from "node:fs";
|
|
7
8
|
import { meter } from "../../libs/metering/mod.js";
|
|
8
|
-
import {
|
|
9
|
+
import { Packed } from "../../libs/packed/mod.js";
|
|
9
10
|
const config = await fetch(self.name).then(res => res.json());
|
|
10
11
|
const helper = new Worker(import.meta.resolve("../helper/bin.js"), { name: self.name, type: "module" });
|
|
11
12
|
function run(module, method, params, mode, maxsparks) {
|
|
@@ -15,11 +16,11 @@ function run(module, method, params, mode, maxsparks) {
|
|
|
15
16
|
const caches = new Map();
|
|
16
17
|
const reads = new Array();
|
|
17
18
|
const writes = new Array();
|
|
18
|
-
const pack_encode = (
|
|
19
|
-
return Writable.writeToBytesOrThrow(new
|
|
19
|
+
const pack_encode = (value) => {
|
|
20
|
+
return Writable.writeToBytesOrThrow(new Packed(value));
|
|
20
21
|
};
|
|
21
22
|
const pack_decode = (bytes) => {
|
|
22
|
-
return Readable.readFromBytesOrThrow(
|
|
23
|
+
return Readable.readFromBytesOrThrow(Packed, bytes);
|
|
23
24
|
};
|
|
24
25
|
const sparks_consume = (amount) => {
|
|
25
26
|
sparks += amount;
|
|
@@ -116,15 +117,21 @@ function run(module, method, params, mode, maxsparks) {
|
|
|
116
117
|
from_base16: (text) => {
|
|
117
118
|
return Uint8Array.fromHex(text);
|
|
118
119
|
},
|
|
119
|
-
to_base16: (
|
|
120
|
-
return
|
|
120
|
+
to_base16: (blob) => {
|
|
121
|
+
return blob.toHex();
|
|
121
122
|
},
|
|
122
123
|
from_base64: (text) => {
|
|
123
124
|
return Uint8Array.fromBase64(text);
|
|
124
125
|
},
|
|
125
|
-
to_base64: (
|
|
126
|
-
return
|
|
126
|
+
to_base64: (blob) => {
|
|
127
|
+
return blob.toBase64();
|
|
127
128
|
},
|
|
129
|
+
encode: (value) => {
|
|
130
|
+
return pack_encode(value);
|
|
131
|
+
},
|
|
132
|
+
decode: (blob) => {
|
|
133
|
+
return pack_decode(blob);
|
|
134
|
+
}
|
|
128
135
|
};
|
|
129
136
|
imports["texts"] = {
|
|
130
137
|
length: (text) => {
|
|
@@ -173,12 +180,6 @@ function run(module, method, params, mode, maxsparks) {
|
|
|
173
180
|
if (value === undefined)
|
|
174
181
|
throw new Error("Not found");
|
|
175
182
|
return value;
|
|
176
|
-
},
|
|
177
|
-
encode: (pack) => {
|
|
178
|
-
return pack_encode(pack);
|
|
179
|
-
},
|
|
180
|
-
decode: (blob) => {
|
|
181
|
-
return pack_decode(blob);
|
|
182
183
|
}
|
|
183
184
|
};
|
|
184
185
|
imports["bigints"] = {
|
|
@@ -272,7 +273,7 @@ function run(module, method, params, mode, maxsparks) {
|
|
|
272
273
|
load(moduleAsString);
|
|
273
274
|
if (typeof exports[moduleAsString][methodAsString] !== "function")
|
|
274
275
|
throw new Error("Not found");
|
|
275
|
-
return
|
|
276
|
+
return exports[moduleAsString][methodAsString](...paramsAsPack);
|
|
276
277
|
},
|
|
277
278
|
load: (moduleAsBytes) => {
|
|
278
279
|
return readFileSync(`${config.scripts.path}/${moduleAsBytes.toHex()}.wasm`);
|
|
@@ -379,8 +380,11 @@ function run(module, method, params, mode, maxsparks) {
|
|
|
379
380
|
const { instance } = load(module);
|
|
380
381
|
if (typeof instance.exports[method] !== "function")
|
|
381
382
|
throw new Error("Not found");
|
|
382
|
-
const
|
|
383
|
-
if (
|
|
383
|
+
const args = pack_decode(params);
|
|
384
|
+
if (!Array.isArray(args))
|
|
385
|
+
throw new Error("Params is not an array");
|
|
386
|
+
const returned = instance.exports[method](...args);
|
|
387
|
+
if (mode !== 1)
|
|
384
388
|
return pack_encode([logs, reads, writes, returned, sparks]);
|
|
385
389
|
if (writes.length) {
|
|
386
390
|
const result = new Int32Array(new SharedArrayBuffer(4 + 4));
|
package/package.json
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@hazae41/bobine",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.17",
|
|
5
5
|
"description": "A blockchain in your garage",
|
|
6
6
|
"repository": "github:hazae41/bobine",
|
|
7
7
|
"author": "hazae41",
|
|
8
8
|
"license": "MIT",
|
|
9
9
|
"scripts": {
|
|
10
10
|
"examine": "deno lint ./src && deno check ./src && deno test -R ./src",
|
|
11
|
-
"version": "deno -RW ./x.vsync.ts && git add deno.json",
|
|
12
|
-
"prepare": "deno -RW ./x.dsync.ts && deno install",
|
|
13
11
|
"prepack": "rm -rf ./out && tsc && tscousin",
|
|
14
12
|
"produce": "deno run -A ./src/mod.ts serve --env=./.env.local",
|
|
15
13
|
"develop": "deno run -A ./src/mod.ts serve --env=./.env.local --dev"
|
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 = {}));
|