Switch to .mts files and build typescript bindings in genbindings.sh
authorMatt Corallo <git@bluematt.me>
Wed, 5 Jan 2022 06:18:33 +0000 (06:18 +0000)
committerMatt Corallo <git@bluematt.me>
Thu, 6 Jan 2022 18:24:49 +0000 (18:24 +0000)
genbindings.sh
ts/node/fs.d.ts [new file with mode: 0755]
ts/node/index.d.ts [new file with mode: 0755]
ts/node/package.json [new file with mode: 0755]
ts/test/index.html
ts/test/test.mjs [new file with mode: 0644]
ts/tsconfig.json [new file with mode: 0644]
typescript_strings.py

index 13dba4a0a5189ad88d8f8f657271823d9a7f9094..a378a1e154eaadfda05cb08ecf9a5b4a220e4394 100755 (executable)
@@ -1,15 +1,17 @@
 #!/bin/bash
 usage() {
-       echo "USAGE: path/to/ldk-c-bindings \"JNI_CFLAGS\" debug android"
+       echo "USAGE: path/to/ldk-c-bindings \"JNI_CFLAGS\" debug android web"
        echo "For JNI_CFLAGS you probably want -I/usr/lib/jvm/java-11-openjdk-amd64/include/ -I/usr/lib/jvm/java-11-openjdk-amd64/include/linux/"
        echo "debug should either be true, false, or leaks"
        echo "debug of leaks turns on leak tracking on an optimized release bianry"
        echo "android should either be true or false"
+       echo "web should either be true or false"
        exit 1
 }
 [ "$1" = "" ] && usage
 [ "$3" != "true" -a "$3" != "false" -a "$3" != "leaks" ] && usage
 [ "$4" != "true" -a "$4" != "false" ] && usage
+[ "$5" != "true" -a "$5" != "false" ] && usage
 
 set -x
 
@@ -173,8 +175,12 @@ fi
 
 echo "Creating TS bindings..."
 mkdir -p ts/{enums,structs}
-rm -f ts/{enums,structs}/*.ts
-./genbindings.py "./lightning.h" ts ts ts $DEBUG_ARG typescript
+rm -f ts/{enums,structs,}/*.{mjs,mts}
+if [ "$5" = "true" ]; then
+       ./genbindings.py "./lightning.h" ts ts ts $DEBUG_ARG typescript node
+else
+       ./genbindings.py "./lightning.h" ts ts ts $DEBUG_ARG typescript browser
+fi
 rm -f ts/bindings.c
 if [ "$3" = "true" ]; then
        echo "#define LDK_DEBUG_BUILD" > ts/bindings.c
@@ -198,3 +204,20 @@ if [ "$3" = "true" ]; then
 else
        $COMPILE -o liblightningjs_release.wasm -s -Os -I"$1"/lightning-c-bindings/include/ ts/bindings.c "$1"/lightning-c-bindings/target/wasm32-wasi/release/libldk.a $EXTRA_LINK
 fi
+
+if [ -x "$(which tsc)" ]; then
+       cd ts
+rm -r structs # TODO: Make the human-types compile
+       if [ "$5" = "false" ]; then
+               tsc
+       else
+               tsc --types node --typeRoots .
+               cd ..
+               if [ -x "$(which node)" ]; then
+                       NODE_V="$(node --version)"
+                       if [ "${NODE_V:1:2}" -gt 14 ]; then
+                               node ts/test/
+                       fi
+               fi
+       fi
+fi
diff --git a/ts/node/fs.d.ts b/ts/node/fs.d.ts
new file mode 100755 (executable)
index 0000000..af20d13
--- /dev/null
@@ -0,0 +1,16 @@
+// Minimal subset of the node 'fs' library that we depend on.
+// May be (c) Microsoft licensed under the MIT license, but API's are generally not copyrightable per recent precedent.
+declare module 'fs' {
+    export type PathLike = string | Buffer | URL;
+    export type PathOrFileDescriptor = PathLike | number;
+    export function readFileSync(
+        path: PathOrFileDescriptor,
+        options?: {
+            encoding?: null | undefined;
+            flag?: string | undefined;
+        } | null
+    ): Buffer;
+}
+declare module 'node:fs' {
+    export * from 'fs';
+}
diff --git a/ts/node/index.d.ts b/ts/node/index.d.ts
new file mode 100755 (executable)
index 0000000..516375f
--- /dev/null
@@ -0,0 +1,3 @@
+// Minimal subset of the node 'fs' library that we depend on.
+// May be (c) Microsoft licensed under the MIT license, but API's are generally not copyrightable per recent precedent.
+/// <reference path="fs.d.ts" />
diff --git a/ts/node/package.json b/ts/node/package.json
new file mode 100755 (executable)
index 0000000..c0b7589
--- /dev/null
@@ -0,0 +1,8 @@
+{
+    "name": "@types/node",
+    "version": "17.0.8",
+    "description": "TypeScript definitions for Node.js",
+    "homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node",
+    "contributors": [],
+    "types": "index.d.ts"
+}
index 3e7c6694d19d2a1af903e56446ba73ec8f214fcd..3b0ba69f49d4fe1d53fa24267919b46e4d945c4d 100644 (file)
@@ -3,114 +3,7 @@
 <html>
 <head></head>
 <body>
-<script type="module">
-       (async() => {
-               const imports = {};
-               imports.wasi_snapshot_preview1 = {
-                       "fd_write" : () => {
-                               console.log("ABORT");
-                       },
-                       "random_get" : () => {
-                               console.log("ABORT");
-                       },
-                       "environ_sizes_get" : () => {
-                               console.log("wasi_snapshot_preview1:environ_sizes_get");
-                       },
-                       "proc_exit" : () => {
-                               console.log("wasi_snapshot_preview1:proc_exit");
-                       },
-                       "environ_get" : () => {
-                               console.log("wasi_snapshot_preview1:environ_get");
-                       },
-               };
-               imports.env = {};
-
-               const memory = new WebAssembly.Memory({initial: 256});
-               imports.env.memoryBase = 0;
-               imports.env.memory = memory;
-               imports.env.tableBase = 0;
-               imports.env.table = new WebAssembly.Table({ initial: 4, element: 'anyfunc' });
-
-               imports.env["abort"] = function() {
-                       console.error("ABORT");
-               };
-               imports.env["js_log"] = function(argument) {
-                       console.log("HI");
-                       const res = decodeUint8Array(argument, false);
-                       console.log(res);
-               };
-               imports.env["js_free"] = function(argument) {
-                       console.log('integer passed from wasm:', argument);
-               };
-               imports.env["js_invoke_function"] = function(fn, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10) {
-                       console.log('function called from wasm:', fn);
-               };
-
-               const stream = fetch('../../liblightningjs.wasm');
-               const { instance: wasmInstance } = await WebAssembly.instantiateStreaming(stream, imports);
-               const wasm = wasmInstance.exports;
-
-
-               const encodeUint8Array = (inputArray) => {
-                       const cArrayPointer = wasm.TS_malloc(inputArray.length + 4);
-                       const arrayLengthView = new Uint32Array(memory.buffer, cArrayPointer, 1);
-                       arrayLengthView[0] = inputArray.length;
-                       const arrayMemoryView = new Uint8Array(memory.buffer, cArrayPointer + 4, inputArray.length);
-                       arrayMemoryView.set(inputArray);
-                       return cArrayPointer;
-               }
-
-               const encodeUint32Array = (inputArray) => {
-                       const cArrayPointer = wasm.TS_malloc((inputArray.length + 1) * 4);
-                       const arrayMemoryView = new Uint32Array(memory.buffer, cArrayPointer, inputArray.length);
-                       arrayMemoryView[0] = inputArray.length;
-                       arrayMemoryView.set(inputArray, 1);
-                       return cArrayPointer;
-               }
-
-               const getArrayLength = (arrayPointer) => {
-                       const arraySizeViewer = new Uint32Array(
-                               memory.buffer, // value
-                               arrayPointer, // offset
-                               1 // one int
-                       );
-                       return arraySizeViewer[0];
-               }
-               const decodeUint8Array = (arrayPointer, free = true) => {
-                       const arraySize = getArrayLength(arrayPointer);
-                       const actualArrayViewer = new Uint8Array(
-                               memory.buffer, // value
-                               arrayPointer + 4, // offset (ignoring length bytes)
-                               arraySize // uint8 count
-                       );
-                       // Clone the contents, TODO: In the future we should wrap the Viewer in a class that
-                       // will free the underlying memory when it becomes unreachable instead of copying here.
-                       const actualArray = actualArrayViewer.slice(0, arraySize);
-                       if (free) {
-                               wasm.TS_free(arrayPointer);
-                       }
-                       return actualArray;
-               }
-
-               const result = wasm.TS_CResult_boolLightningErrorZ_ok(true);
-               console.assert(wasm.TS_CResult_boolLightningErrorZ_is_ok(result));
-               console.assert(wasm.TS_LDKCResult_boolLightningErrorZ_get_ok(result));
-               wasm.TS_CResult_boolLightningErrorZ_free(result);
-               console.assert(wasm.TS_CResult_boolLightningErrorZ_ok(false) == result); // malloc doesn't need to guarantee this, but currently does
-               console.assert(wasm.TS_CResult_boolLightningErrorZ_is_ok(result));
-               console.assert(!wasm.TS_LDKCResult_boolLightningErrorZ_get_ok(result));
-               wasm.TS_CResult_boolLightningErrorZ_free(result);
-
-               var pk_arr = [];
-               for (var i = 0; i < 33; i++) { pk_arr[i] = 42; }
-               const pk_bytes = encodeUint8Array(pk_arr);
-               const pk_res = wasm.TS_CResult_PublicKeyErrorZ_ok(pk_bytes);
-               console.assert(wasm.TS_CResult_PublicKeyErrorZ_is_ok(pk_res));
-               const pk_res_bytes = wasm.TS_LDKCResult_PublicKeyErrorZ_get_ok(pk_res);
-               wasm.TS_CResult_PublicKeyErrorZ_free(pk_res);
-
-               console.log("pass");
-       })();
+<script type="module" src="test.mjs">
 </script>
 </body>
 </html>
diff --git a/ts/test/test.mjs b/ts/test/test.mjs
new file mode 100644 (file)
index 0000000..1bcf0f1
--- /dev/null
@@ -0,0 +1,24 @@
+import * as ldk from "../bindings.mjs";
+async function run_tests() {
+       await ldk.initializeWasm("../../liblightningjs.wasm");
+       const result = ldk.CResult_boolLightningErrorZ_ok(true);
+       console.assert(ldk.CResult_boolLightningErrorZ_is_ok(result));
+       console.assert(ldk.CResult_boolLightningErrorZ_get_ok(result));
+       ldk.CResult_boolLightningErrorZ_free(result);
+       console.assert(ldk.CResult_boolLightningErrorZ_ok(false) == result); // malloc doesn't need to guarantee this, but currently does
+       console.assert(ldk.CResult_boolLightningErrorZ_is_ok(result));
+       console.assert(!ldk.CResult_boolLightningErrorZ_get_ok(result));
+       ldk.CResult_boolLightningErrorZ_free(result);
+
+       /*var pk_arr = [];
+       for (var i = 0; i < 33; i++) { pk_arr[i] = 42; }
+       const pk_bytes = encodeUint8Array(pk_arr);
+       const pk_res = wasm.TS_CResult_PublicKeyErrorZ_ok(pk_bytes);
+       console.assert(wasm.TS_CResult_PublicKeyErrorZ_is_ok(pk_res));
+       const pk_res_bytes = wasm.TS_LDKCResult_PublicKeyErrorZ_get_ok(pk_res);
+       wasm.TS_CResult_PublicKeyErrorZ_free(pk_res);*/
+
+       console.log("pass");
+}
+
+run_tests();
diff --git a/ts/tsconfig.json b/ts/tsconfig.json
new file mode 100644 (file)
index 0000000..922bd17
--- /dev/null
@@ -0,0 +1,29 @@
+{
+  "compilerOptions": {
+    "target": "es2021",
+    "module": "es2020",
+    "forceConsistentCasingInFileNames": true,
+
+    "strict": true,
+    "noImplicitAny": false,
+    "strictNullChecks": false,
+    "strictFunctionTypes": true,
+    "strictBindCallApply": true,
+    "strictPropertyInitialization": false,
+    "noImplicitThis": true,
+    "useUnknownInCatchVariables": true,
+    "alwaysStrict": true,
+    "noUnusedLocals": false,
+    "noUnusedParameters": false,
+    "exactOptionalPropertyTypes": false,
+    "noImplicitReturns": true,
+    "noFallthroughCasesInSwitch": true,
+    "noUncheckedIndexedAccess": true,
+    "noImplicitOverride": true,
+    "noPropertyAccessFromIndexSignature": true,
+    "allowUnusedLabels": false,
+    "allowUnreachableCode": false,
+
+    "skipLibCheck": true
+  }
+}
index 29ccc3e45933e5819b3a4a61cbb1c29b24e6c351..914c0189cf0167dd3fcf9dafa616f2eeb306e383 100644 (file)
@@ -282,11 +282,11 @@ void __attribute__((visibility("default"))) TS_free(uint32_t ptr) {
 
         self.hu_struct_file_prefix = f"""
 import CommonBase from './CommonBase';
-import * as bindings from '../bindings' // TODO: figure out location
+import * as bindings from '../bindings.mjs'
 
 """
         self.c_fn_ty_pfx = ""
-        self.file_ext = ".ts"
+        self.file_ext = ".mts"
         self.ptr_c_ty = "uint32_t"
         self.ptr_native_ty = "number"
         self.result_c_ty = "uint32_t"