@wasm-fmt/gofmt 0.2.0 → 0.3.1

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/.editorconfig ADDED
@@ -0,0 +1,11 @@
1
+ # Check http://editorconfig.org for more information
2
+ # This is the main config file for this project:
3
+ root = true
4
+
5
+ [*]
6
+ charset = utf-8
7
+ trim_trailing_whitespace = true
8
+ end_of_line = lf
9
+ indent_style = space
10
+ insert_final_newline = true
11
+ indent_size = 4
package/.gitattributes ADDED
@@ -0,0 +1,5 @@
1
+ # Auto detect text files and perform LF normalization
2
+ * text=auto
3
+ *.js linguist-detectable=false
4
+ *.mjs linguist-detectable=false
5
+ *.sh linguist-detectable=false
package/README.md CHANGED
@@ -10,27 +10,25 @@ npm install @wasm-fmt/gofmt
10
10
  # Usage
11
11
 
12
12
  ```JavaScript
13
- import { format } from '@wasm-fmt/gofmt';
13
+ import init, { format } from '@wasm-fmt/gofmt';
14
+
15
+ await init();
14
16
 
15
17
  const source = `
16
18
  package main
17
19
  import "fmt"
18
- func main(){fmt.Println("Hello, 世界")}
20
+ func main(){fmt.Println("Hello, 世界")
21
+ }
19
22
  `;
20
23
 
21
- const formatted = await format(source);
24
+ const formatted = format(source);
22
25
  console.log(formatted);
23
26
  ```
24
27
 
25
28
  Vite users tip:
26
29
 
27
30
  ```JavaScript
28
- import { format } from '@wasm-fmt/gofmt';
29
- import wasmUrl from "@wasm-fmt/gofmt/lib.wasm?url";
30
-
31
- // ...
32
-
33
- const formatted = await format(source, new URL(wasmUrl, import.meta.url));
31
+ import init, { format } from '@wasm-fmt/gofmt/vite';
34
32
  ```
35
33
 
36
34
  # Build from source
package/gen_patch.sh ADDED
@@ -0,0 +1,23 @@
1
+ current_dir=$(pwd)
2
+ tmp_dir=$(mktemp -d)
3
+
4
+ cd $tmp_dir
5
+ git init
6
+
7
+ cp $(tinygo env TINYGOROOT)/targets/wasm_exec.js $tmp_dir/go_wasm.js
8
+ git add -f .
9
+ git commit -m "init"
10
+
11
+ cp $current_dir/go_wasm.js $tmp_dir/go_wasm.js
12
+ git add -f .
13
+
14
+ git diff \
15
+ --cached \
16
+ --no-color \
17
+ --ignore-space-at-eol \
18
+ --no-ext-diff \
19
+ --src-prefix=a/ \
20
+ --dst-prefix=b/ \
21
+ >$current_dir/go_wasm.patch
22
+
23
+ rm -rf $tmp_dir
package/go_wasm.js CHANGED
@@ -6,7 +6,6 @@
6
6
 
7
7
  const encoder = new TextEncoder("utf-8");
8
8
  const decoder = new TextDecoder("utf-8");
9
- var logLine = [];
10
9
 
11
10
  export class Go {
12
11
  constructor() {
@@ -125,50 +124,12 @@
125
124
  this.importObject = {
126
125
  wasi_snapshot_preview1: {
127
126
  // https://github.com/WebAssembly/WASI/blob/main/phases/snapshot/docs.md#fd_write
128
- fd_write: function(fd, iovs_ptr, iovs_len, nwritten_ptr) {
129
- let nwritten = 0;
130
- if (fd == 1) {
131
- for (let iovs_i=0; iovs_i<iovs_len;iovs_i++) {
132
- let iov_ptr = iovs_ptr+iovs_i*8; // assuming wasm32
133
- let ptr = mem().getUint32(iov_ptr + 0, true);
134
- let len = mem().getUint32(iov_ptr + 4, true);
135
- nwritten += len;
136
- for (let i=0; i<len; i++) {
137
- let c = mem().getUint8(ptr+i);
138
- if (c == 13) { // CR
139
- // ignore
140
- } else if (c == 10) { // LF
141
- // write line
142
- let line = decoder.decode(new Uint8Array(logLine));
143
- logLine = [];
144
- console.log(line);
145
- } else {
146
- logLine.push(c);
147
- }
148
- }
149
- }
150
- } else {
151
- console.error('invalid file descriptor:', fd);
152
- }
153
- mem().setUint32(nwritten_ptr, nwritten, true);
154
- return 0;
155
- },
156
- fd_close: () => 0, // dummy
157
- fd_fdstat_get: () => 0, // dummy
158
- fd_seek: () => 0, // dummy
159
- "proc_exit": (code) => {
160
- if (global.process) {
161
- // Node.js
162
- process.exit(code);
163
- } else {
164
- // Can't exit in a browser.
165
- throw 'trying to exit with code ' + code;
166
- }
167
- },
168
- random_get: (bufPtr, bufLen) => {
169
- crypto.getRandomValues(loadSlice(bufPtr, bufLen));
170
- return 0;
171
- },
127
+ fd_write() {},
128
+ fd_close() {},
129
+ fd_fdstat_get() {},
130
+ fd_seek() {},
131
+ proc_exit() {},
132
+ random_get() {}
172
133
  },
173
134
  env: {
174
135
  // func ticks() float64
@@ -337,22 +298,6 @@
337
298
  };
338
299
  }
339
300
 
340
- storeString(str) {
341
- const addr = this._inst.exports.getBuffer();
342
- const buf = this._inst.exports.memory.buffer;
343
-
344
- const mem = new Uint8Array(buf);
345
- const view = mem.subarray(addr);
346
- return encoder.encodeInto(str, view).written;
347
- }
348
-
349
- loadString(len) {
350
- const addr = this._inst.exports.getBuffer();
351
- const buf = this._inst.exports.memory.buffer;
352
-
353
- return decoder.decode(new DataView(buf, addr, len));
354
- }
355
-
356
301
  async run(instance) {
357
302
  this._inst = instance;
358
303
  this._values = [ // JS values that Go currently has references to, indexed by reference id
@@ -361,7 +306,12 @@
361
306
  null,
362
307
  true,
363
308
  false,
364
- "undefined" != typeof globalThis ? globalThis : global || self,
309
+ // fake global
310
+ {
311
+ set format(fn){ instance.format = fn; },
312
+ Array,
313
+ Object,
314
+ },
365
315
  this,
366
316
  ];
367
317
  this._goRefCounts = []; // number of references that Go has to a JS value, indexed by reference id
@@ -369,8 +319,6 @@
369
319
  this._idPool = []; // unused ids that have been garbage collected
370
320
  this.exited = false; // whether the Go program has exited
371
321
 
372
- const mem = new DataView(this._inst.exports.memory.buffer)
373
-
374
322
  while (true) {
375
323
  const callbackPromise = new Promise((resolve) => {
376
324
  this._resolveCallbackPromise = () => {
package/lib.d.ts CHANGED
@@ -1,4 +1,2 @@
1
- export declare function format(
2
- input: string,
3
- wasm_url?: string | URL
4
- ): Promise<string>;
1
+ export default function init(wasm_url?: string | URL): Promise<void>;
2
+ export declare function format(input: string): string;
package/lib.js CHANGED
@@ -1,39 +1,47 @@
1
1
  import { Go } from "./go_wasm.js";
2
2
  const go = new Go();
3
3
 
4
- let mod;
4
+ let inst;
5
+
6
+ export default async function init(wasm_url) {
7
+ if (inst) {
8
+ return await inst;
9
+ }
5
10
 
6
- export async function format(input, wasm_url) {
7
- if (!mod) {
8
11
  if (!wasm_url) {
9
- wasm_url = new URL("lib.wasm", import.meta.url);
12
+ wasm_url = new URL("lib.wasm", import.meta.url);
10
13
  }
11
14
 
12
15
  if (typeof wasm_url === "string") {
13
- wasm_url = new URL(wasm_url);
16
+ wasm_url = new URL(wasm_url);
14
17
  }
15
18
 
16
- if (typeof __webpack_require__ !== "function" && wasm_url.protocol === "file:") {
17
- const fs = await import("node:fs");
18
- const bytes = fs.readFileSync(wasm_url);
19
- mod = new WebAssembly.Module(bytes);
20
- } else if ("compileStreaming" in WebAssembly) {
21
- mod = await WebAssembly.compileStreaming(fetch(wasm_url));
19
+ if (
20
+ typeof __webpack_require__ !== "function" &&
21
+ wasm_url.protocol === "file:"
22
+ ) {
23
+ inst = import("node:fs/promises")
24
+ .then((fs) => fs.readFile(wasm_url))
25
+ .then((bytes) => WebAssembly.instantiate(bytes, go.importObject));
26
+ } else if ("instantiateStreaming" in WebAssembly) {
27
+ inst = WebAssembly.instantiateStreaming(
28
+ fetch(wasm_url),
29
+ go.importObject
30
+ );
22
31
  } else {
23
- const response = await fetch(wasm_url);
24
- const bytes = await response.arrayBuffer();
25
- mod = new WebAssembly.Module(bytes);
32
+ inst = fetch(wasm_url)
33
+ .then((response) => response.arrayBuffer())
34
+ .then((bytes) => WebAssembly.instantiate(bytes, go.importObject));
26
35
  }
27
- }
28
-
29
- const inst = new WebAssembly.Instance(mod, go.importObject);
30
- go.run(inst);
36
+ inst = (await inst).instance;
37
+ go.run(inst);
38
+ }
31
39
 
32
- const input_len = go.storeString(input);
33
- const output_len = inst.exports.format(input_len);
34
- if (output_len < 0) {
35
- throw new Error(go.loadString(-output_len));
36
- }
40
+ export function format(input) {
41
+ const [err, result] = inst.format(input);
42
+ if (err) {
43
+ throw new Error(result);
44
+ }
37
45
 
38
- return go.loadString(output_len);
46
+ return result;
39
47
  }
package/lib.wasm CHANGED
Binary file
package/package.json CHANGED
@@ -1,11 +1,23 @@
1
1
  {
2
2
  "name": "@wasm-fmt/gofmt",
3
3
  "author": "magic-akari <akari.ccino@gamil.com>",
4
- "version": "0.2.0",
4
+ "version": "0.3.1",
5
5
  "description": "wasm based gofmt",
6
6
  "main": "lib.js",
7
7
  "types": "lib.d.ts",
8
8
  "type": "module",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./lib.d.ts",
12
+ "default": "./lib.js"
13
+ },
14
+ "./vite": {
15
+ "types": "./lib.d.ts",
16
+ "default": "./vite.js"
17
+ },
18
+ "./package.json": "./package.json",
19
+ "./*": "./*"
20
+ },
9
21
  "scripts": {
10
22
  "go_wasm": "cp $(tinygo env TINYGOROOT)/targets/wasm_exec.js ./go_wasm.js",
11
23
  "patch": "git apply ./go_wasm.patch",
@@ -16,7 +28,11 @@
16
28
  "engines": {
17
29
  "node": ">=16.17.0"
18
30
  },
19
- "keywords": [],
31
+ "keywords": [
32
+ "wasm",
33
+ "golang",
34
+ "formatter"
35
+ ],
20
36
  "license": "MIT",
21
37
  "publishConfig": {
22
38
  "access": "public"
package/src/lib.go CHANGED
@@ -1,31 +1,23 @@
1
1
  package main
2
2
 
3
- import "go/format"
3
+ import (
4
+ "go/format"
5
+ "syscall/js"
6
+ )
4
7
 
5
- const buf_len = 8192
8
+ func Format(this js.Value, args []js.Value) any {
9
+ input := ([]byte)(args[0].String())
6
10
 
7
- var buf [buf_len]byte
8
-
9
- //go:export getBuffer
10
- func GetBuffer() *byte {
11
- return &buf[0]
12
- }
13
-
14
- //go:export format
15
- func Format(input_len uint) int {
16
- input := buf[:input_len]
17
11
  output, err := format.Source(input)
18
12
  if err != nil {
19
- return -copy(buf[:], []byte(err.Error()))
13
+ return []any{true, err.Error()}
20
14
  }
21
- result := len(output)
22
15
 
23
- if result > buf_len {
24
- return -copy(buf[:], []byte("Buffer out of memory"))
25
- }
26
-
27
- copy(buf[:], output)
28
- return result
16
+ return []any{false, string(output)}
29
17
  }
30
18
 
31
- func main() {}
19
+ func main() {
20
+ done := make(chan bool)
21
+ js.Global().Set("format", js.FuncOf(Format))
22
+ <-done
23
+ }
package/test.js CHANGED
@@ -1,31 +1,29 @@
1
- import assert from "node:assert";
1
+ import assert from "node:assert/strict";
2
2
  import fs from "node:fs/promises";
3
3
  import test from "node:test";
4
- import { format } from "./lib.js";
4
+ import init, { format } from "./lib.js";
5
+
6
+ await init();
5
7
 
6
8
  const files = (await fs.readdir("testdata"))
7
- .filter((f) => f.endsWith(".input"))
8
- .map((f) => {
9
- return {
10
- input_name: f,
11
- golden_name: f.replace(".input", ".golden"),
12
- };
13
- });
9
+ .filter((f) => f.endsWith(".input"))
10
+ .map((f) => {
11
+ return {
12
+ input_name: f,
13
+ golden_name: f.replace(".input", ".golden"),
14
+ };
15
+ });
14
16
 
15
17
  for (const { input_name, golden_name } of files) {
16
- await test(
17
- `format ${input_name}`,
18
- { skip: input_name[0] === "." },
19
- async () => {
20
- const [input, expected] = await Promise.all(
21
- [input_name, golden_name].map((f) =>
22
- fs.readFile(`testdata/${f}`, "utf-8")
23
- )
24
- );
18
+ test(`format ${input_name}`, { skip: input_name[0] === "." }, async () => {
19
+ const [input, expected] = await Promise.all(
20
+ [input_name, golden_name].map((f) =>
21
+ fs.readFile(`testdata/${f}`, "utf-8")
22
+ )
23
+ );
25
24
 
26
- const actual = await format(input);
25
+ const actual = format(input);
27
26
 
28
- assert.strictEqual(actual, expected);
29
- }
30
- );
27
+ assert.equal(actual, expected);
28
+ });
31
29
  }
package/vite.js ADDED
@@ -0,0 +1,8 @@
1
+ import init from "./lib.js";
2
+ import wasm from "./lib.wasm?url";
3
+
4
+ export default function __wbg_init(input = wasm) {
5
+ return init(input);
6
+ }
7
+
8
+ export * from "./lib.js";