@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 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 jsr:@hazae41/bobine
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 = {}));
@@ -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, events] = event.data.params;
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 events)
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;
@@ -1,3 +1,4 @@
1
+ /// <reference lib="deno.ns" />
1
2
  import { readFileSync } from "node:fs";
2
3
  import process from "node:process";
3
4
  import { serveWithEnv } from "./mod.js";
@@ -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 { Pack } from "../../libs/packs/mod.js";
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 Pack([wasmAsBytes, saltAsBytes]));
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();
@@ -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 { Pack } from "../../libs/packs/mod.js";
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 = (pack) => {
19
- return Writable.writeToBytesOrThrow(new Pack(pack));
19
+ const pack_encode = (value) => {
20
+ return Writable.writeToBytesOrThrow(new Packed(value));
20
21
  };
21
22
  const pack_decode = (bytes) => {
22
- return Readable.readFromBytesOrThrow(Pack, bytes);
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: (bytes) => {
120
- return bytes.toHex();
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: (bytes) => {
126
- return bytes.toBase64();
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 new Pack([exports[moduleAsString][methodAsString](...paramsAsPack.values)]);
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 returned = [instance.exports[method](...pack_decode(params))];
383
- if (mode !== 2)
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.12",
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"
@@ -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
- }
@@ -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 = {}));