@hazae41/bobine 0.0.8 → 0.0.10
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 +22 -22
- package/out/libs/metering/mod.js +23 -12
- package/out/libs/packs/mod.d.ts +1 -1
- package/out/libs/packs/mod.js +41 -23
- package/out/mod.js +1 -16
- package/out/mods/server/bin.js +5 -5
- package/out/mods/worker/bin.js +47 -9
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -17,9 +17,9 @@ https://bobine.tech/
|
|
|
17
17
|
|
|
18
18
|
\* There are no built-in accounting concepts, only pure generic APIs for cryptography and storage
|
|
19
19
|
|
|
20
|
-
##
|
|
20
|
+
## Usage
|
|
21
21
|
|
|
22
|
-
###
|
|
22
|
+
### Running the server
|
|
23
23
|
|
|
24
24
|
Install the binary with Deno
|
|
25
25
|
|
|
@@ -58,13 +58,15 @@ Run the server
|
|
|
58
58
|
bobine serve --env=./.env.local
|
|
59
59
|
```
|
|
60
60
|
|
|
61
|
-
|
|
61
|
+
Or you can install `@hazae41/bobine` and use the `serve()` function
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
### Making your own module
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
You can clone my [AssemblyScript starter](https://github.com/hazae41/create-bobine-assemblyscript-module) to get started with AssemblyScript
|
|
66
66
|
|
|
67
|
-
###
|
|
67
|
+
### Using the HTTP API
|
|
68
|
+
|
|
69
|
+
#### POST /api/create
|
|
68
70
|
|
|
69
71
|
Creates a new module using some WebAssembly code and some unique salt
|
|
70
72
|
|
|
@@ -76,7 +78,7 @@ Accepts a form data with the following fields
|
|
|
76
78
|
|
|
77
79
|
- `effort` as bytes = some unique 32 bytes whose sha256 `hash` validates `((2n ** 256n) / BigInt("0x" + hash.toHex())) > (code.length + salt.length)`
|
|
78
80
|
|
|
79
|
-
|
|
81
|
+
#### POST /api/execute
|
|
80
82
|
|
|
81
83
|
Execute some function on a module
|
|
82
84
|
|
|
@@ -90,7 +92,7 @@ Accepts a form data with the following fields
|
|
|
90
92
|
|
|
91
93
|
- `effort` as bytes = some unique 32 bytes whose sha256 `hash` whose result in `((2n ** 256n) / BigInt("0x" + hash.toHex()))` will be the maximum number of sparks (gas) used
|
|
92
94
|
|
|
93
|
-
|
|
95
|
+
#### POST /api/simulate
|
|
94
96
|
|
|
95
97
|
Simulate some function on a module (it won't write anything to storage and will execute in mode `2` so verifications such as signatures can be skipped)
|
|
96
98
|
|
|
@@ -104,11 +106,11 @@ Accepts a form data with the following fields
|
|
|
104
106
|
|
|
105
107
|
- `effort` as bytes = some unique 32 bytes whose sha256 `hash` whose result in `((2n ** 256n) / BigInt("0x" + hash.toHex()))` will be the maximum number of sparks (gas) used
|
|
106
108
|
|
|
107
|
-
|
|
109
|
+
### Using the WebAssembly API
|
|
108
110
|
|
|
109
111
|
The WebAssembly VM extensively uses reference types for its API and for module-to-module communication
|
|
110
112
|
|
|
111
|
-
|
|
113
|
+
#### Using the WebAssembly API via AssemblyScript
|
|
112
114
|
|
|
113
115
|
You can use [stdbob](https://github.com/hazae41/stdbob) to easily import AssemblyScript declarations for all internal modules
|
|
114
116
|
|
|
@@ -126,9 +128,7 @@ And you can declare external modules by using the module address as hex
|
|
|
126
128
|
declare function add(x: externref, y: externref): externref
|
|
127
129
|
```
|
|
128
130
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
#### blobs
|
|
131
|
+
#### Blobs module
|
|
132
132
|
|
|
133
133
|
You can pass bytes between modules by storing them in the blob storage and loading them via reference
|
|
134
134
|
|
|
@@ -142,7 +142,7 @@ You can pass bytes between modules by storing them in the blob storage and loadi
|
|
|
142
142
|
|
|
143
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
144
|
|
|
145
|
-
####
|
|
145
|
+
#### BigInts module
|
|
146
146
|
|
|
147
147
|
You can work with infinite-precision bigints
|
|
148
148
|
|
|
@@ -168,7 +168,7 @@ You can work with infinite-precision bigints
|
|
|
168
168
|
|
|
169
169
|
- `bigints.from_base10(base16: blobref): bigintref` = convert base10 utf8 bytes to bigint
|
|
170
170
|
|
|
171
|
-
####
|
|
171
|
+
#### Packs module
|
|
172
172
|
|
|
173
173
|
You can pack various arguments (numbers, refs) into a pack which can be passed between modules and/or encoded/decoded into bytes
|
|
174
174
|
|
|
@@ -225,7 +225,7 @@ function writePack(pack: packref) {
|
|
|
225
225
|
|
|
226
226
|
- `packs.length(pack: packref): i32` = get the length of a pack
|
|
227
227
|
|
|
228
|
-
####
|
|
228
|
+
#### Environment module
|
|
229
229
|
|
|
230
230
|
Get infos about the executing environment
|
|
231
231
|
|
|
@@ -233,7 +233,7 @@ Get infos about the executing environment
|
|
|
233
233
|
|
|
234
234
|
- `env.uuid(): blobref` = get the unique uuid of this environment (similar to a chain id)
|
|
235
235
|
|
|
236
|
-
####
|
|
236
|
+
#### Modules module
|
|
237
237
|
|
|
238
238
|
Modules are identified by their address as a blob of bytes (pure sha256-output 32-length bytes without any encoding)
|
|
239
239
|
|
|
@@ -245,7 +245,7 @@ Modules are identified by their address as a blob of bytes (pure sha256-output 3
|
|
|
245
245
|
|
|
246
246
|
- `modules.self(): blobref` = get your module address as blob
|
|
247
247
|
|
|
248
|
-
####
|
|
248
|
+
#### Storage module
|
|
249
249
|
|
|
250
250
|
You can use a private storage (it works like storage and events at the same time)
|
|
251
251
|
|
|
@@ -253,13 +253,13 @@ You can use a private storage (it works like storage and events at the same time
|
|
|
253
253
|
|
|
254
254
|
- `storage.get(key: blobref): blobref` = get the latest value from storage at key
|
|
255
255
|
|
|
256
|
-
####
|
|
256
|
+
#### SHA-256 module
|
|
257
257
|
|
|
258
258
|
Use the SHA-256 hashing algorithm
|
|
259
259
|
|
|
260
260
|
- `sha256.digest(payload: blobref): blobref` = hash the payload and returns the digest
|
|
261
261
|
|
|
262
|
-
####
|
|
262
|
+
#### Ed25519 module
|
|
263
263
|
|
|
264
264
|
Use the Ed25519 signing algorithm
|
|
265
265
|
|
|
@@ -267,11 +267,11 @@ Use the Ed25519 signing algorithm
|
|
|
267
267
|
|
|
268
268
|
- `ed25519.sign(payload: blobref): blobref` = (experimental) sign payload using the miner's private key
|
|
269
269
|
|
|
270
|
-
####
|
|
270
|
+
#### Symbols module (experimental)
|
|
271
271
|
|
|
272
272
|
- `symbols.create(): symbolref` = create a unique reference that can be passed around
|
|
273
273
|
|
|
274
|
-
####
|
|
274
|
+
#### References module (experimental)
|
|
275
275
|
|
|
276
276
|
- `refs.numerize(ref: symbolref/blobref/packref): i32` = translate any reference into a unique private pointer that can be stored into data structures
|
|
277
277
|
|
package/out/libs/metering/mod.js
CHANGED
|
@@ -1,17 +1,28 @@
|
|
|
1
1
|
import * as Wasm from "@hazae41/wasm";
|
|
2
2
|
export function meter(module, from, name) {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
if (wimport == null)
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
3
|
+
let wtype = module.body.sections.find(section => section.kind === Wasm.TypeSection.kind);
|
|
4
|
+
if (wtype == null) {
|
|
5
|
+
wtype = new Wasm.TypeSection([]);
|
|
6
|
+
module.body.sections.unshift(wtype);
|
|
7
|
+
}
|
|
8
|
+
let wimport = module.body.sections.find(section => section.kind === Wasm.ImportSection.kind);
|
|
9
|
+
if (wimport == null) {
|
|
10
|
+
wimport = new Wasm.ImportSection([]);
|
|
11
|
+
const before = module.body.sections.findLastIndex(section => section.kind < Wasm.ImportSection.kind);
|
|
12
|
+
module.body.sections.splice(before + 1, 0, wimport);
|
|
13
|
+
}
|
|
14
|
+
let wexport = module.body.sections.find(section => section.kind === Wasm.ExportSection.kind);
|
|
15
|
+
if (wexport == null) {
|
|
16
|
+
wexport = new Wasm.ExportSection([]);
|
|
17
|
+
const before = module.body.sections.findLastIndex(section => section.kind < Wasm.ExportSection.kind);
|
|
18
|
+
module.body.sections.splice(before + 1, 0, wexport);
|
|
19
|
+
}
|
|
20
|
+
let wcode = module.body.sections.find(section => section.kind === Wasm.CodeSection.kind);
|
|
21
|
+
if (wcode == null) {
|
|
22
|
+
wcode = new Wasm.CodeSection([]);
|
|
23
|
+
const before = module.body.sections.findLastIndex(section => section.kind < Wasm.CodeSection.kind);
|
|
24
|
+
module.body.sections.splice(before + 1, 0, wcode);
|
|
25
|
+
}
|
|
15
26
|
const wstart = module.body.sections.find(section => section.kind === Wasm.StartSection.kind);
|
|
16
27
|
wtype.descriptors.push({ prefix: Wasm.TypeSection.FuncType.kind, subtypes: [], body: new Wasm.TypeSection.FuncType([0x7f], []) });
|
|
17
28
|
wimport.descriptors.unshift({ from: new TextEncoder().encode(from), name: new TextEncoder().encode(name), body: new Wasm.ImportSection.FunctionImport(wtype.descriptors.length - 1) });
|
package/out/libs/packs/mod.d.ts
CHANGED
|
@@ -6,6 +6,6 @@ export declare class Pack {
|
|
|
6
6
|
writeOrThrow(cursor: Cursor): void;
|
|
7
7
|
}
|
|
8
8
|
export declare namespace Pack {
|
|
9
|
-
type Value = null |
|
|
9
|
+
type Value = null | Pack | number | Uint8Array | string | bigint;
|
|
10
10
|
function readOrThrow(cursor: Cursor): Pack;
|
|
11
11
|
}
|
package/out/libs/packs/mod.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
// deno-lint-ignore-file no-namespace
|
|
2
2
|
export class Pack {
|
|
3
3
|
values;
|
|
4
4
|
constructor(values) {
|
|
@@ -11,22 +11,27 @@ export class Pack {
|
|
|
11
11
|
size += 1;
|
|
12
12
|
continue;
|
|
13
13
|
}
|
|
14
|
-
if (
|
|
15
|
-
size += 1 +
|
|
14
|
+
if (value instanceof Pack) {
|
|
15
|
+
size += 1 + value.sizeOrThrow();
|
|
16
16
|
continue;
|
|
17
17
|
}
|
|
18
|
-
if (typeof value === "
|
|
19
|
-
|
|
20
|
-
const data = Uint8Array.fromHex(text.length % 2 === 1 ? "0" + text : text);
|
|
21
|
-
size += 1 + 4 + data.length;
|
|
18
|
+
if (typeof value === "number") {
|
|
19
|
+
size += 1 + 4;
|
|
22
20
|
continue;
|
|
23
21
|
}
|
|
24
22
|
if (value instanceof Uint8Array) {
|
|
25
23
|
size += 1 + 4 + value.length;
|
|
26
24
|
continue;
|
|
27
25
|
}
|
|
28
|
-
if (value
|
|
29
|
-
|
|
26
|
+
if (typeof value === "string") {
|
|
27
|
+
const data = new TextEncoder().encode(value);
|
|
28
|
+
size += 1 + 4 + data.length;
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
if (typeof value === "bigint") {
|
|
32
|
+
const text = value.toString(16);
|
|
33
|
+
const data = Uint8Array.fromHex(text.length % 2 === 1 ? "0" + text : text);
|
|
34
|
+
size += 1 + 4 + data.length;
|
|
30
35
|
continue;
|
|
31
36
|
}
|
|
32
37
|
throw new Error("Unknown pack value");
|
|
@@ -40,17 +45,14 @@ export class Pack {
|
|
|
40
45
|
cursor.writeUint8OrThrow(1);
|
|
41
46
|
continue;
|
|
42
47
|
}
|
|
43
|
-
if (
|
|
48
|
+
if (value instanceof Pack) {
|
|
44
49
|
cursor.writeUint8OrThrow(2);
|
|
45
|
-
|
|
50
|
+
value.writeOrThrow(cursor);
|
|
46
51
|
continue;
|
|
47
52
|
}
|
|
48
|
-
if (typeof value === "
|
|
53
|
+
if (typeof value === "number") {
|
|
49
54
|
cursor.writeUint8OrThrow(3);
|
|
50
|
-
|
|
51
|
-
const data = Uint8Array.fromHex(text.length % 2 === 1 ? "0" + text : text);
|
|
52
|
-
cursor.writeUint32OrThrow(data.length, true);
|
|
53
|
-
cursor.writeOrThrow(data);
|
|
55
|
+
cursor.writeFloat64OrThrow(value, true);
|
|
54
56
|
continue;
|
|
55
57
|
}
|
|
56
58
|
if (value instanceof Uint8Array) {
|
|
@@ -59,9 +61,19 @@ export class Pack {
|
|
|
59
61
|
cursor.writeOrThrow(value);
|
|
60
62
|
continue;
|
|
61
63
|
}
|
|
62
|
-
if (value
|
|
64
|
+
if (typeof value === "string") {
|
|
63
65
|
cursor.writeUint8OrThrow(5);
|
|
64
|
-
|
|
66
|
+
const data = new TextEncoder().encode(value);
|
|
67
|
+
cursor.writeUint32OrThrow(data.length, true);
|
|
68
|
+
cursor.writeOrThrow(data);
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
if (typeof value === "bigint") {
|
|
72
|
+
cursor.writeUint8OrThrow(6);
|
|
73
|
+
const text = value.toString(16);
|
|
74
|
+
const data = Uint8Array.fromHex(text.length % 2 === 1 ? "0" + text : text);
|
|
75
|
+
cursor.writeUint32OrThrow(data.length, true);
|
|
76
|
+
cursor.writeOrThrow(data);
|
|
65
77
|
continue;
|
|
66
78
|
}
|
|
67
79
|
throw new Error("Unknown pack value");
|
|
@@ -82,13 +94,11 @@ export class Pack {
|
|
|
82
94
|
continue;
|
|
83
95
|
}
|
|
84
96
|
if (type === 2) {
|
|
85
|
-
values.push(
|
|
97
|
+
values.push(Pack.readOrThrow(cursor));
|
|
86
98
|
continue;
|
|
87
99
|
}
|
|
88
100
|
if (type === 3) {
|
|
89
|
-
|
|
90
|
-
const data = cursor.readOrThrow(size);
|
|
91
|
-
values.push(BigInt("0x" + data.toHex()));
|
|
101
|
+
values.push(cursor.readFloat64OrThrow(true));
|
|
92
102
|
continue;
|
|
93
103
|
}
|
|
94
104
|
if (type === 4) {
|
|
@@ -97,7 +107,15 @@ export class Pack {
|
|
|
97
107
|
continue;
|
|
98
108
|
}
|
|
99
109
|
if (type === 5) {
|
|
100
|
-
|
|
110
|
+
const size = cursor.readUint32OrThrow(true);
|
|
111
|
+
const data = cursor.readOrThrow(size);
|
|
112
|
+
values.push(new TextDecoder().decode(data));
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
if (type === 6) {
|
|
116
|
+
const size = cursor.readUint32OrThrow(true);
|
|
117
|
+
const data = cursor.readOrThrow(size);
|
|
118
|
+
values.push(BigInt("0x" + data.toHex()));
|
|
101
119
|
continue;
|
|
102
120
|
}
|
|
103
121
|
throw new Error("Unknown pack type");
|
package/out/mod.js
CHANGED
|
@@ -15,24 +15,9 @@ export async function main(args) {
|
|
|
15
15
|
await server.main(subargs);
|
|
16
16
|
return;
|
|
17
17
|
}
|
|
18
|
-
if (arg === "create") {
|
|
19
|
-
console.log("Create command is not implemented yet.");
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
if (arg === "execute") {
|
|
23
|
-
console.log("Execute command is not implemented yet.");
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
if (arg === "simulate") {
|
|
27
|
-
console.log("Simulate command is not implemented yet.");
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
18
|
break;
|
|
31
19
|
}
|
|
32
|
-
console.log("
|
|
33
|
-
console.log("- create <wasm file as path> [salt as hex]");
|
|
34
|
-
console.log("- execute <module as hex> <function name> [args as pack as hex]");
|
|
35
|
-
console.log("- simulate <module as hex> <function name> [args as pack as hex]");
|
|
20
|
+
console.log("serve [--env=<env file as path>] [--port=<port>] [--dev]");
|
|
36
21
|
return;
|
|
37
22
|
}
|
|
38
23
|
if (import.meta.main) {
|
package/out/mods/server/bin.js
CHANGED
|
@@ -2,7 +2,7 @@ import { readFileSync } from "node:fs";
|
|
|
2
2
|
import process from "node:process";
|
|
3
3
|
import { serveWithEnv } from "./mod.js";
|
|
4
4
|
export async function main(args) {
|
|
5
|
-
const
|
|
5
|
+
const options = {};
|
|
6
6
|
for (let i = 0; i < args.length; i++) {
|
|
7
7
|
const arg = args[i];
|
|
8
8
|
if (arg.startsWith("--env=")) {
|
|
@@ -10,15 +10,15 @@ export async function main(args) {
|
|
|
10
10
|
continue;
|
|
11
11
|
}
|
|
12
12
|
if (arg.startsWith("--port=")) {
|
|
13
|
-
|
|
13
|
+
options.port = Number(arg.slice("--port=".length));
|
|
14
14
|
continue;
|
|
15
15
|
}
|
|
16
16
|
if (arg.startsWith("--cert=")) {
|
|
17
|
-
|
|
17
|
+
options.cert = readFileSync(arg.slice("--cert=".length), "utf8");
|
|
18
18
|
continue;
|
|
19
19
|
}
|
|
20
20
|
if (arg.startsWith("--key=")) {
|
|
21
|
-
|
|
21
|
+
options.key = readFileSync(arg.slice("--key=".length), "utf8");
|
|
22
22
|
continue;
|
|
23
23
|
}
|
|
24
24
|
if (arg === "--dev=true") {
|
|
@@ -35,7 +35,7 @@ export async function main(args) {
|
|
|
35
35
|
}
|
|
36
36
|
throw new Error(`Unknown argument: ${arg}`);
|
|
37
37
|
}
|
|
38
|
-
const { port = Number(process.env.PORT) || 8080, cert = process.env.CERT != null ? readFileSync(process.env.CERT, "utf8") : undefined, key = process.env.KEY != null ? readFileSync(process.env.KEY, "utf8") : undefined, } =
|
|
38
|
+
const { port = Number(process.env.PORT) || 8080, cert = process.env.CERT != null ? readFileSync(process.env.CERT, "utf8") : undefined, key = process.env.KEY != null ? readFileSync(process.env.KEY, "utf8") : undefined, } = options;
|
|
39
39
|
const server = await serveWithEnv();
|
|
40
40
|
const route = async (request) => {
|
|
41
41
|
if (request.method === "OPTIONS")
|
package/out/mods/worker/bin.js
CHANGED
|
@@ -89,14 +89,14 @@ function run(module, method, params, mode, maxsparks) {
|
|
|
89
89
|
const view = new Uint8Array(memory.buffer, offset >>> 0, length >>> 0);
|
|
90
90
|
return view.slice();
|
|
91
91
|
},
|
|
92
|
-
size: (blob) => {
|
|
93
|
-
return blob.length;
|
|
94
|
-
},
|
|
95
92
|
load: (blob, offset) => {
|
|
96
93
|
const { memory } = current.instance.exports;
|
|
97
94
|
const view = new Uint8Array(memory.buffer, offset >>> 0, blob.length);
|
|
98
95
|
view.set(blob);
|
|
99
96
|
},
|
|
97
|
+
length: (blob) => {
|
|
98
|
+
return blob.length;
|
|
99
|
+
},
|
|
100
100
|
concat: (left, right) => {
|
|
101
101
|
const concat = new Uint8Array(left.length + right.length);
|
|
102
102
|
concat.set(left, 0);
|
|
@@ -106,17 +106,55 @@ function run(module, method, params, mode, maxsparks) {
|
|
|
106
106
|
equals: (left, right) => {
|
|
107
107
|
return !Buffer.compare(left, right);
|
|
108
108
|
},
|
|
109
|
-
|
|
110
|
-
return
|
|
109
|
+
includes: (haystack, needle) => {
|
|
110
|
+
return haystack.toHex().includes(needle.toHex());
|
|
111
111
|
},
|
|
112
|
-
|
|
113
|
-
return
|
|
112
|
+
slice: (blob, start, end) => {
|
|
113
|
+
return blob.slice(start >>> 0, end >>> 0);
|
|
114
|
+
},
|
|
115
|
+
from_base16: (text) => {
|
|
116
|
+
return Uint8Array.fromHex(text);
|
|
114
117
|
},
|
|
115
118
|
to_base16: (bytes) => {
|
|
116
|
-
return
|
|
119
|
+
return bytes.toHex();
|
|
120
|
+
},
|
|
121
|
+
from_base64: (text) => {
|
|
122
|
+
return Uint8Array.fromBase64(text);
|
|
117
123
|
},
|
|
118
124
|
to_base64: (bytes) => {
|
|
119
|
-
return
|
|
125
|
+
return bytes.toBase64();
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
imports["texts"] = {
|
|
129
|
+
length: (text) => {
|
|
130
|
+
return new TextEncoder().encode(text).length;
|
|
131
|
+
},
|
|
132
|
+
concat: (left, right) => {
|
|
133
|
+
return left + right;
|
|
134
|
+
},
|
|
135
|
+
equals: (left, right) => {
|
|
136
|
+
return left === right;
|
|
137
|
+
},
|
|
138
|
+
includes: (haystack, needle) => {
|
|
139
|
+
return haystack.includes(needle);
|
|
140
|
+
},
|
|
141
|
+
slice: (text, start, end) => {
|
|
142
|
+
return text.slice(start >>> 0, end >>> 0);
|
|
143
|
+
},
|
|
144
|
+
from_utf8: (bytes) => {
|
|
145
|
+
return new TextDecoder().decode(bytes);
|
|
146
|
+
},
|
|
147
|
+
to_utf8: (text) => {
|
|
148
|
+
return new TextEncoder().encode(text);
|
|
149
|
+
},
|
|
150
|
+
to_uppercase: (text) => {
|
|
151
|
+
return text.toUpperCase();
|
|
152
|
+
},
|
|
153
|
+
to_lowercase: (text) => {
|
|
154
|
+
return text.toLowerCase();
|
|
155
|
+
},
|
|
156
|
+
trim: (text) => {
|
|
157
|
+
return text.trim();
|
|
120
158
|
}
|
|
121
159
|
};
|
|
122
160
|
imports["packs"] = {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@hazae41/bobine",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.10",
|
|
5
5
|
"description": "A blockchain in your garage",
|
|
6
6
|
"repository": "github:hazae41/bobine",
|
|
7
7
|
"author": "hazae41",
|
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
"version": "deno -RW ./x.vsync.ts && git add deno.json",
|
|
12
12
|
"prepare": "deno -RW ./x.dsync.ts && deno install",
|
|
13
13
|
"prepack": "rm -rf ./out && tsc && tscousin",
|
|
14
|
-
"produce": "deno run -A ./src/
|
|
15
|
-
"develop": "deno run -A ./src/
|
|
14
|
+
"produce": "deno run -A ./src/mod.ts serve --env=./.env.local",
|
|
15
|
+
"develop": "deno run -A ./src/mod.ts serve --env=./.env.local --dev"
|
|
16
16
|
},
|
|
17
17
|
"files": [
|
|
18
18
|
"./out"
|