detached 65a4ec6

build(systemviews): ignore generated runtime assets

commit
65a4ec6d994fdaa3b1cf1f7d68a7a74426241291
author
brice · · 2026-04-12 09:04 UTC
parent
dfc9db1
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
3 files · +2 -575
M .gitignore +2 -0
@@ -65,6 +65,8 @@ tmp/go-cache/
6565 tmp/go-mod/
6666 tmp/
6767 assets/webui
68+assets/systemviews/systemviews.wasm
69+assets/systemviews/wasm_exec.js
6870
6971 # Node/TypeScript related
7072 node_modules/
@@ -65,6 +65,8 @@ tmp/go-cache/
65 tmp/go-mod/65 tmp/go-mod/
66 tmp/66 tmp/
67 assets/webui67 assets/webui
68+assets/systemviews/systemviews.wasm
69+assets/systemviews/wasm_exec.js
68 70
69 # Node/TypeScript related71 # Node/TypeScript related
70 node_modules/72 node_modules/
D assets/systemviews/systemviews.wasm +0 -0 binary file: no text diff

binary file: no text diff

D assets/systemviews/wasm_exec.js +0 -575
@@ -1,575 +0,0 @@
1-// Copyright 2018 The Go Authors. All rights reserved.
2-// Use of this source code is governed by a BSD-style
3-// license that can be found in the LICENSE file.
4-
5-"use strict";
6-
7-(() => {
8- const enosys = () => {
9- const err = new Error("not implemented");
10- err.code = "ENOSYS";
11- return err;
12- };
13-
14- if (!globalThis.fs) {
15- let outputBuf = "";
16- globalThis.fs = {
17- constants: { O_WRONLY: -1, O_RDWR: -1, O_CREAT: -1, O_TRUNC: -1, O_APPEND: -1, O_EXCL: -1, O_DIRECTORY: -1 }, // unused
18- writeSync(fd, buf) {
19- outputBuf += decoder.decode(buf);
20- const nl = outputBuf.lastIndexOf("\n");
21- if (nl != -1) {
22- console.log(outputBuf.substring(0, nl));
23- outputBuf = outputBuf.substring(nl + 1);
24- }
25- return buf.length;
26- },
27- write(fd, buf, offset, length, position, callback) {
28- if (offset !== 0 || length !== buf.length || position !== null) {
29- callback(enosys());
30- return;
31- }
32- const n = this.writeSync(fd, buf);
33- callback(null, n);
34- },
35- chmod(path, mode, callback) { callback(enosys()); },
36- chown(path, uid, gid, callback) { callback(enosys()); },
37- close(fd, callback) { callback(enosys()); },
38- fchmod(fd, mode, callback) { callback(enosys()); },
39- fchown(fd, uid, gid, callback) { callback(enosys()); },
40- fstat(fd, callback) { callback(enosys()); },
41- fsync(fd, callback) { callback(null); },
42- ftruncate(fd, length, callback) { callback(enosys()); },
43- lchown(path, uid, gid, callback) { callback(enosys()); },
44- link(path, link, callback) { callback(enosys()); },
45- lstat(path, callback) { callback(enosys()); },
46- mkdir(path, perm, callback) { callback(enosys()); },
47- open(path, flags, mode, callback) { callback(enosys()); },
48- read(fd, buffer, offset, length, position, callback) { callback(enosys()); },
49- readdir(path, callback) { callback(enosys()); },
50- readlink(path, callback) { callback(enosys()); },
51- rename(from, to, callback) { callback(enosys()); },
52- rmdir(path, callback) { callback(enosys()); },
53- stat(path, callback) { callback(enosys()); },
54- symlink(path, link, callback) { callback(enosys()); },
55- truncate(path, length, callback) { callback(enosys()); },
56- unlink(path, callback) { callback(enosys()); },
57- utimes(path, atime, mtime, callback) { callback(enosys()); },
58- };
59- }
60-
61- if (!globalThis.process) {
62- globalThis.process = {
63- getuid() { return -1; },
64- getgid() { return -1; },
65- geteuid() { return -1; },
66- getegid() { return -1; },
67- getgroups() { throw enosys(); },
68- pid: -1,
69- ppid: -1,
70- umask() { throw enosys(); },
71- cwd() { throw enosys(); },
72- chdir() { throw enosys(); },
73- }
74- }
75-
76- if (!globalThis.path) {
77- globalThis.path = {
78- resolve(...pathSegments) {
79- return pathSegments.join("/");
80- }
81- }
82- }
83-
84- if (!globalThis.crypto) {
85- throw new Error("globalThis.crypto is not available, polyfill required (crypto.getRandomValues only)");
86- }
87-
88- if (!globalThis.performance) {
89- throw new Error("globalThis.performance is not available, polyfill required (performance.now only)");
90- }
91-
92- if (!globalThis.TextEncoder) {
93- throw new Error("globalThis.TextEncoder is not available, polyfill required");
94- }
95-
96- if (!globalThis.TextDecoder) {
97- throw new Error("globalThis.TextDecoder is not available, polyfill required");
98- }
99-
100- const encoder = new TextEncoder("utf-8");
101- const decoder = new TextDecoder("utf-8");
102-
103- globalThis.Go = class {
104- constructor() {
105- this.argv = ["js"];
106- this.env = {};
107- this.exit = (code) => {
108- if (code !== 0) {
109- console.warn("exit code:", code);
110- }
111- };
112- this._exitPromise = new Promise((resolve) => {
113- this._resolveExitPromise = resolve;
114- });
115- this._pendingEvent = null;
116- this._scheduledTimeouts = new Map();
117- this._nextCallbackTimeoutID = 1;
118-
119- const setInt64 = (addr, v) => {
120- this.mem.setUint32(addr + 0, v, true);
121- this.mem.setUint32(addr + 4, Math.floor(v / 4294967296), true);
122- }
123-
124- const setInt32 = (addr, v) => {
125- this.mem.setUint32(addr + 0, v, true);
126- }
127-
128- const getInt64 = (addr) => {
129- const low = this.mem.getUint32(addr + 0, true);
130- const high = this.mem.getInt32(addr + 4, true);
131- return low + high * 4294967296;
132- }
133-
134- const loadValue = (addr) => {
135- const f = this.mem.getFloat64(addr, true);
136- if (f === 0) {
137- return undefined;
138- }
139- if (!isNaN(f)) {
140- return f;
141- }
142-
143- const id = this.mem.getUint32(addr, true);
144- return this._values[id];
145- }
146-
147- const storeValue = (addr, v) => {
148- const nanHead = 0x7FF80000;
149-
150- if (typeof v === "number" && v !== 0) {
151- if (isNaN(v)) {
152- this.mem.setUint32(addr + 4, nanHead, true);
153- this.mem.setUint32(addr, 0, true);
154- return;
155- }
156- this.mem.setFloat64(addr, v, true);
157- return;
158- }
159-
160- if (v === undefined) {
161- this.mem.setFloat64(addr, 0, true);
162- return;
163- }
164-
165- let id = this._ids.get(v);
166- if (id === undefined) {
167- id = this._idPool.pop();
168- if (id === undefined) {
169- id = this._values.length;
170- }
171- this._values[id] = v;
172- this._goRefCounts[id] = 0;
173- this._ids.set(v, id);
174- }
175- this._goRefCounts[id]++;
176- let typeFlag = 0;
177- switch (typeof v) {
178- case "object":
179- if (v !== null) {
180- typeFlag = 1;
181- }
182- break;
183- case "string":
184- typeFlag = 2;
185- break;
186- case "symbol":
187- typeFlag = 3;
188- break;
189- case "function":
190- typeFlag = 4;
191- break;
192- }
193- this.mem.setUint32(addr + 4, nanHead | typeFlag, true);
194- this.mem.setUint32(addr, id, true);
195- }
196-
197- const loadSlice = (addr) => {
198- const array = getInt64(addr + 0);
199- const len = getInt64(addr + 8);
200- return new Uint8Array(this._inst.exports.mem.buffer, array, len);
201- }
202-
203- const loadSliceOfValues = (addr) => {
204- const array = getInt64(addr + 0);
205- const len = getInt64(addr + 8);
206- const a = new Array(len);
207- for (let i = 0; i < len; i++) {
208- a[i] = loadValue(array + i * 8);
209- }
210- return a;
211- }
212-
213- const loadString = (addr) => {
214- const saddr = getInt64(addr + 0);
215- const len = getInt64(addr + 8);
216- return decoder.decode(new DataView(this._inst.exports.mem.buffer, saddr, len));
217- }
218-
219- const testCallExport = (a, b) => {
220- this._inst.exports.testExport0();
221- return this._inst.exports.testExport(a, b);
222- }
223-
224- const timeOrigin = Date.now() - performance.now();
225- this.importObject = {
226- _gotest: {
227- add: (a, b) => a + b,
228- callExport: testCallExport,
229- },
230- gojs: {
231- // Go's SP does not change as long as no Go code is running. Some operations (e.g. calls, getters and setters)
232- // may synchronously trigger a Go event handler. This makes Go code get executed in the middle of the imported
233- // function. A goroutine can switch to a new stack if the current stack is too small (see morestack function).
234- // This changes the SP, thus we have to update the SP used by the imported function.
235-
236- // func wasmExit(code int32)
237- "runtime.wasmExit": (sp) => {
238- sp >>>= 0;
239- const code = this.mem.getInt32(sp + 8, true);
240- this.exited = true;
241- delete this._inst;
242- delete this._values;
243- delete this._goRefCounts;
244- delete this._ids;
245- delete this._idPool;
246- this.exit(code);
247- },
248-
249- // func wasmWrite(fd uintptr, p unsafe.Pointer, n int32)
250- "runtime.wasmWrite": (sp) => {
251- sp >>>= 0;
252- const fd = getInt64(sp + 8);
253- const p = getInt64(sp + 16);
254- const n = this.mem.getInt32(sp + 24, true);
255- fs.writeSync(fd, new Uint8Array(this._inst.exports.mem.buffer, p, n));
256- },
257-
258- // func resetMemoryDataView()
259- "runtime.resetMemoryDataView": (sp) => {
260- sp >>>= 0;
261- this.mem = new DataView(this._inst.exports.mem.buffer);
262- },
263-
264- // func nanotime1() int64
265- "runtime.nanotime1": (sp) => {
266- sp >>>= 0;
267- setInt64(sp + 8, (timeOrigin + performance.now()) * 1000000);
268- },
269-
270- // func walltime() (sec int64, nsec int32)
271- "runtime.walltime": (sp) => {
272- sp >>>= 0;
273- const msec = (new Date).getTime();
274- setInt64(sp + 8, msec / 1000);
275- this.mem.setInt32(sp + 16, (msec % 1000) * 1000000, true);
276- },
277-
278- // func scheduleTimeoutEvent(delay int64) int32
279- "runtime.scheduleTimeoutEvent": (sp) => {
280- sp >>>= 0;
281- const id = this._nextCallbackTimeoutID;
282- this._nextCallbackTimeoutID++;
283- this._scheduledTimeouts.set(id, setTimeout(
284- () => {
285- this._resume();
286- while (this._scheduledTimeouts.has(id)) {
287- // for some reason Go failed to register the timeout event, log and try again
288- // (temporary workaround for https://github.com/golang/go/issues/28975)
289- console.warn("scheduleTimeoutEvent: missed timeout event");
290- this._resume();
291- }
292- },
293- getInt64(sp + 8),
294- ));
295- this.mem.setInt32(sp + 16, id, true);
296- },
297-
298- // func clearTimeoutEvent(id int32)
299- "runtime.clearTimeoutEvent": (sp) => {
300- sp >>>= 0;
301- const id = this.mem.getInt32(sp + 8, true);
302- clearTimeout(this._scheduledTimeouts.get(id));
303- this._scheduledTimeouts.delete(id);
304- },
305-
306- // func getRandomData(r []byte)
307- "runtime.getRandomData": (sp) => {
308- sp >>>= 0;
309- crypto.getRandomValues(loadSlice(sp + 8));
310- },
311-
312- // func finalizeRef(v ref)
313- "syscall/js.finalizeRef": (sp) => {
314- sp >>>= 0;
315- const id = this.mem.getUint32(sp + 8, true);
316- this._goRefCounts[id]--;
317- if (this._goRefCounts[id] === 0) {
318- const v = this._values[id];
319- this._values[id] = null;
320- this._ids.delete(v);
321- this._idPool.push(id);
322- }
323- },
324-
325- // func stringVal(value string) ref
326- "syscall/js.stringVal": (sp) => {
327- sp >>>= 0;
328- storeValue(sp + 24, loadString(sp + 8));
329- },
330-
331- // func valueGet(v ref, p string) ref
332- "syscall/js.valueGet": (sp) => {
333- sp >>>= 0;
334- const result = Reflect.get(loadValue(sp + 8), loadString(sp + 16));
335- sp = this._inst.exports.getsp() >>> 0; // see comment above
336- storeValue(sp + 32, result);
337- },
338-
339- // func valueSet(v ref, p string, x ref)
340- "syscall/js.valueSet": (sp) => {
341- sp >>>= 0;
342- Reflect.set(loadValue(sp + 8), loadString(sp + 16), loadValue(sp + 32));
343- },
344-
345- // func valueDelete(v ref, p string)
346- "syscall/js.valueDelete": (sp) => {
347- sp >>>= 0;
348- Reflect.deleteProperty(loadValue(sp + 8), loadString(sp + 16));
349- },
350-
351- // func valueIndex(v ref, i int) ref
352- "syscall/js.valueIndex": (sp) => {
353- sp >>>= 0;
354- storeValue(sp + 24, Reflect.get(loadValue(sp + 8), getInt64(sp + 16)));
355- },
356-
357- // valueSetIndex(v ref, i int, x ref)
358- "syscall/js.valueSetIndex": (sp) => {
359- sp >>>= 0;
360- Reflect.set(loadValue(sp + 8), getInt64(sp + 16), loadValue(sp + 24));
361- },
362-
363- // func valueCall(v ref, m string, args []ref) (ref, bool)
364- "syscall/js.valueCall": (sp) => {
365- sp >>>= 0;
366- try {
367- const v = loadValue(sp + 8);
368- const m = Reflect.get(v, loadString(sp + 16));
369- const args = loadSliceOfValues(sp + 32);
370- const result = Reflect.apply(m, v, args);
371- sp = this._inst.exports.getsp() >>> 0; // see comment above
372- storeValue(sp + 56, result);
373- this.mem.setUint8(sp + 64, 1);
374- } catch (err) {
375- sp = this._inst.exports.getsp() >>> 0; // see comment above
376- storeValue(sp + 56, err);
377- this.mem.setUint8(sp + 64, 0);
378- }
379- },
380-
381- // func valueInvoke(v ref, args []ref) (ref, bool)
382- "syscall/js.valueInvoke": (sp) => {
383- sp >>>= 0;
384- try {
385- const v = loadValue(sp + 8);
386- const args = loadSliceOfValues(sp + 16);
387- const result = Reflect.apply(v, undefined, args);
388- sp = this._inst.exports.getsp() >>> 0; // see comment above
389- storeValue(sp + 40, result);
390- this.mem.setUint8(sp + 48, 1);
391- } catch (err) {
392- sp = this._inst.exports.getsp() >>> 0; // see comment above
393- storeValue(sp + 40, err);
394- this.mem.setUint8(sp + 48, 0);
395- }
396- },
397-
398- // func valueNew(v ref, args []ref) (ref, bool)
399- "syscall/js.valueNew": (sp) => {
400- sp >>>= 0;
401- try {
402- const v = loadValue(sp + 8);
403- const args = loadSliceOfValues(sp + 16);
404- const result = Reflect.construct(v, args);
405- sp = this._inst.exports.getsp() >>> 0; // see comment above
406- storeValue(sp + 40, result);
407- this.mem.setUint8(sp + 48, 1);
408- } catch (err) {
409- sp = this._inst.exports.getsp() >>> 0; // see comment above
410- storeValue(sp + 40, err);
411- this.mem.setUint8(sp + 48, 0);
412- }
413- },
414-
415- // func valueLength(v ref) int
416- "syscall/js.valueLength": (sp) => {
417- sp >>>= 0;
418- setInt64(sp + 16, parseInt(loadValue(sp + 8).length));
419- },
420-
421- // valuePrepareString(v ref) (ref, int)
422- "syscall/js.valuePrepareString": (sp) => {
423- sp >>>= 0;
424- const str = encoder.encode(String(loadValue(sp + 8)));
425- storeValue(sp + 16, str);
426- setInt64(sp + 24, str.length);
427- },
428-
429- // valueLoadString(v ref, b []byte)
430- "syscall/js.valueLoadString": (sp) => {
431- sp >>>= 0;
432- const str = loadValue(sp + 8);
433- loadSlice(sp + 16).set(str);
434- },
435-
436- // func valueInstanceOf(v ref, t ref) bool
437- "syscall/js.valueInstanceOf": (sp) => {
438- sp >>>= 0;
439- this.mem.setUint8(sp + 24, (loadValue(sp + 8) instanceof loadValue(sp + 16)) ? 1 : 0);
440- },
441-
442- // func copyBytesToGo(dst []byte, src ref) (int, bool)
443- "syscall/js.copyBytesToGo": (sp) => {
444- sp >>>= 0;
445- const dst = loadSlice(sp + 8);
446- const src = loadValue(sp + 32);
447- if (!(src instanceof Uint8Array || src instanceof Uint8ClampedArray)) {
448- this.mem.setUint8(sp + 48, 0);
449- return;
450- }
451- const toCopy = src.subarray(0, dst.length);
452- dst.set(toCopy);
453- setInt64(sp + 40, toCopy.length);
454- this.mem.setUint8(sp + 48, 1);
455- },
456-
457- // func copyBytesToJS(dst ref, src []byte) (int, bool)
458- "syscall/js.copyBytesToJS": (sp) => {
459- sp >>>= 0;
460- const dst = loadValue(sp + 8);
461- const src = loadSlice(sp + 16);
462- if (!(dst instanceof Uint8Array || dst instanceof Uint8ClampedArray)) {
463- this.mem.setUint8(sp + 48, 0);
464- return;
465- }
466- const toCopy = src.subarray(0, dst.length);
467- dst.set(toCopy);
468- setInt64(sp + 40, toCopy.length);
469- this.mem.setUint8(sp + 48, 1);
470- },
471-
472- "debug": (value) => {
473- console.log(value);
474- },
475- }
476- };
477- }
478-
479- async run(instance) {
480- if (!(instance instanceof WebAssembly.Instance)) {
481- throw new Error("Go.run: WebAssembly.Instance expected");
482- }
483- this._inst = instance;
484- this.mem = new DataView(this._inst.exports.mem.buffer);
485- this._values = [ // JS values that Go currently has references to, indexed by reference id
486- NaN,
487- 0,
488- null,
489- true,
490- false,
491- globalThis,
492- this,
493- ];
494- this._goRefCounts = new Array(this._values.length).fill(Infinity); // number of references that Go has to a JS value, indexed by reference id
495- this._ids = new Map([ // mapping from JS values to reference ids
496- [0, 1],
497- [null, 2],
498- [true, 3],
499- [false, 4],
500- [globalThis, 5],
501- [this, 6],
502- ]);
503- this._idPool = []; // unused ids that have been garbage collected
504- this.exited = false; // whether the Go program has exited
505-
506- // Pass command line arguments and environment variables to WebAssembly by writing them to the linear memory.
507- let offset = 4096;
508-
509- const strPtr = (str) => {
510- const ptr = offset;
511- const bytes = encoder.encode(str + "\0");
512- new Uint8Array(this.mem.buffer, offset, bytes.length).set(bytes);
513- offset += bytes.length;
514- if (offset % 8 !== 0) {
515- offset += 8 - (offset % 8);
516- }
517- return ptr;
518- };
519-
520- const argc = this.argv.length;
521-
522- const argvPtrs = [];
523- this.argv.forEach((arg) => {
524- argvPtrs.push(strPtr(arg));
525- });
526- argvPtrs.push(0);
527-
528- const keys = Object.keys(this.env).sort();
529- keys.forEach((key) => {
530- argvPtrs.push(strPtr(`${key}=${this.env[key]}`));
531- });
532- argvPtrs.push(0);
533-
534- const argv = offset;
535- argvPtrs.forEach((ptr) => {
536- this.mem.setUint32(offset, ptr, true);
537- this.mem.setUint32(offset + 4, 0, true);
538- offset += 8;
539- });
540-
541- // The linker guarantees global data starts from at least wasmMinDataAddr.
542- // Keep in sync with cmd/link/internal/ld/data.go:wasmMinDataAddr.
543- const wasmMinDataAddr = 4096 + 8192;
544- if (offset >= wasmMinDataAddr) {
545- throw new Error("total length of command line and environment variables exceeds limit");
546- }
547-
548- this._inst.exports.run(argc, argv);
549- if (this.exited) {
550- this._resolveExitPromise();
551- }
552- await this._exitPromise;
553- }
554-
555- _resume() {
556- if (this.exited) {
557- throw new Error("Go program has already exited");
558- }
559- this._inst.exports.resume();
560- if (this.exited) {
561- this._resolveExitPromise();
562- }
563- }
564-
565- _makeFuncWrapper(id) {
566- const go = this;
567- return function () {
568- const event = { id: id, this: this, args: arguments };
569- go._pendingEvent = event;
570- go._resume();
571- return event.result;
572- };
573- }
574- }
575-})();
@@ -1,575 +0,0 @@
1-// Copyright 2018 The Go Authors. All rights reserved.
2-// Use of this source code is governed by a BSD-style
3-// license that can be found in the LICENSE file.
4-
5-"use strict";
6-
7-(() => {
8- const enosys = () => {
9- const err = new Error("not implemented");
10- err.code = "ENOSYS";
11- return err;
12- };
13-
14- if (!globalThis.fs) {
15- let outputBuf = "";
16- globalThis.fs = {
17- constants: { O_WRONLY: -1, O_RDWR: -1, O_CREAT: -1, O_TRUNC: -1, O_APPEND: -1, O_EXCL: -1, O_DIRECTORY: -1 }, // unused
18- writeSync(fd, buf) {
19- outputBuf += decoder.decode(buf);
20- const nl = outputBuf.lastIndexOf("\n");
21- if (nl != -1) {
22- console.log(outputBuf.substring(0, nl));
23- outputBuf = outputBuf.substring(nl + 1);
24- }
25- return buf.length;
26- },
27- write(fd, buf, offset, length, position, callback) {
28- if (offset !== 0 || length !== buf.length || position !== null) {
29- callback(enosys());
30- return;
31- }
32- const n = this.writeSync(fd, buf);
33- callback(null, n);
34- },
35- chmod(path, mode, callback) { callback(enosys()); },
36- chown(path, uid, gid, callback) { callback(enosys()); },
37- close(fd, callback) { callback(enosys()); },
38- fchmod(fd, mode, callback) { callback(enosys()); },
39- fchown(fd, uid, gid, callback) { callback(enosys()); },
40- fstat(fd, callback) { callback(enosys()); },
41- fsync(fd, callback) { callback(null); },
42- ftruncate(fd, length, callback) { callback(enosys()); },
43- lchown(path, uid, gid, callback) { callback(enosys()); },
44- link(path, link, callback) { callback(enosys()); },
45- lstat(path, callback) { callback(enosys()); },
46- mkdir(path, perm, callback) { callback(enosys()); },
47- open(path, flags, mode, callback) { callback(enosys()); },
48- read(fd, buffer, offset, length, position, callback) { callback(enosys()); },
49- readdir(path, callback) { callback(enosys()); },
50- readlink(path, callback) { callback(enosys()); },
51- rename(from, to, callback) { callback(enosys()); },
52- rmdir(path, callback) { callback(enosys()); },
53- stat(path, callback) { callback(enosys()); },
54- symlink(path, link, callback) { callback(enosys()); },
55- truncate(path, length, callback) { callback(enosys()); },
56- unlink(path, callback) { callback(enosys()); },
57- utimes(path, atime, mtime, callback) { callback(enosys()); },
58- };
59- }
60-
61- if (!globalThis.process) {
62- globalThis.process = {
63- getuid() { return -1; },
64- getgid() { return -1; },
65- geteuid() { return -1; },
66- getegid() { return -1; },
67- getgroups() { throw enosys(); },
68- pid: -1,
69- ppid: -1,
70- umask() { throw enosys(); },
71- cwd() { throw enosys(); },
72- chdir() { throw enosys(); },
73- }
74- }
75-
76- if (!globalThis.path) {
77- globalThis.path = {
78- resolve(...pathSegments) {
79- return pathSegments.join("/");
80- }
81- }
82- }
83-
84- if (!globalThis.crypto) {
85- throw new Error("globalThis.crypto is not available, polyfill required (crypto.getRandomValues only)");
86- }
87-
88- if (!globalThis.performance) {
89- throw new Error("globalThis.performance is not available, polyfill required (performance.now only)");
90- }
91-
92- if (!globalThis.TextEncoder) {
93- throw new Error("globalThis.TextEncoder is not available, polyfill required");
94- }
95-
96- if (!globalThis.TextDecoder) {
97- throw new Error("globalThis.TextDecoder is not available, polyfill required");
98- }
99-
100- const encoder = new TextEncoder("utf-8");
101- const decoder = new TextDecoder("utf-8");
102-
103- globalThis.Go = class {
104- constructor() {
105- this.argv = ["js"];
106- this.env = {};
107- this.exit = (code) => {
108- if (code !== 0) {
109- console.warn("exit code:", code);
110- }
111- };
112- this._exitPromise = new Promise((resolve) => {
113- this._resolveExitPromise = resolve;
114- });
115- this._pendingEvent = null;
116- this._scheduledTimeouts = new Map();
117- this._nextCallbackTimeoutID = 1;
118-
119- const setInt64 = (addr, v) => {
120- this.mem.setUint32(addr + 0, v, true);
121- this.mem.setUint32(addr + 4, Math.floor(v / 4294967296), true);
122- }
123-
124- const setInt32 = (addr, v) => {
125- this.mem.setUint32(addr + 0, v, true);
126- }
127-
128- const getInt64 = (addr) => {
129- const low = this.mem.getUint32(addr + 0, true);
130- const high = this.mem.getInt32(addr + 4, true);
131- return low + high * 4294967296;
132- }
133-
134- const loadValue = (addr) => {
135- const f = this.mem.getFloat64(addr, true);
136- if (f === 0) {
137- return undefined;
138- }
139- if (!isNaN(f)) {
140- return f;
141- }
142-
143- const id = this.mem.getUint32(addr, true);
144- return this._values[id];
145- }
146-
147- const storeValue = (addr, v) => {
148- const nanHead = 0x7FF80000;
149-
150- if (typeof v === "number" && v !== 0) {
151- if (isNaN(v)) {
152- this.mem.setUint32(addr + 4, nanHead, true);
153- this.mem.setUint32(addr, 0, true);
154- return;
155- }
156- this.mem.setFloat64(addr, v, true);
157- return;
158- }
159-
160- if (v === undefined) {
161- this.mem.setFloat64(addr, 0, true);
162- return;
163- }
164-
165- let id = this._ids.get(v);
166- if (id === undefined) {
167- id = this._idPool.pop();
168- if (id === undefined) {
169- id = this._values.length;
170- }
171- this._values[id] = v;
172- this._goRefCounts[id] = 0;
173- this._ids.set(v, id);
174- }
175- this._goRefCounts[id]++;
176- let typeFlag = 0;
177- switch (typeof v) {
178- case "object":
179- if (v !== null) {
180- typeFlag = 1;
181- }
182- break;
183- case "string":
184- typeFlag = 2;
185- break;
186- case "symbol":
187- typeFlag = 3;
188- break;
189- case "function":
190- typeFlag = 4;
191- break;
192- }
193- this.mem.setUint32(addr + 4, nanHead | typeFlag, true);
194- this.mem.setUint32(addr, id, true);
195- }
196-
197- const loadSlice = (addr) => {
198- const array = getInt64(addr + 0);
199- const len = getInt64(addr + 8);
200- return new Uint8Array(this._inst.exports.mem.buffer, array, len);
201- }
202-
203- const loadSliceOfValues = (addr) => {
204- const array = getInt64(addr + 0);
205- const len = getInt64(addr + 8);
206- const a = new Array(len);
207- for (let i = 0; i < len; i++) {
208- a[i] = loadValue(array + i * 8);
209- }
210- return a;
211- }
212-
213- const loadString = (addr) => {
214- const saddr = getInt64(addr + 0);
215- const len = getInt64(addr + 8);
216- return decoder.decode(new DataView(this._inst.exports.mem.buffer, saddr, len));
217- }
218-
219- const testCallExport = (a, b) => {
220- this._inst.exports.testExport0();
221- return this._inst.exports.testExport(a, b);
222- }
223-
224- const timeOrigin = Date.now() - performance.now();
225- this.importObject = {
226- _gotest: {
227- add: (a, b) => a + b,
228- callExport: testCallExport,
229- },
230- gojs: {
231- // Go's SP does not change as long as no Go code is running. Some operations (e.g. calls, getters and setters)
232- // may synchronously trigger a Go event handler. This makes Go code get executed in the middle of the imported
233- // function. A goroutine can switch to a new stack if the current stack is too small (see morestack function).
234- // This changes the SP, thus we have to update the SP used by the imported function.
235-
236- // func wasmExit(code int32)
237- "runtime.wasmExit": (sp) => {
238- sp >>>= 0;
239- const code = this.mem.getInt32(sp + 8, true);
240- this.exited = true;
241- delete this._inst;
242- delete this._values;
243- delete this._goRefCounts;
244- delete this._ids;
245- delete this._idPool;
246- this.exit(code);
247- },
248-
249- // func wasmWrite(fd uintptr, p unsafe.Pointer, n int32)
250- "runtime.wasmWrite": (sp) => {
251- sp >>>= 0;
252- const fd = getInt64(sp + 8);
253- const p = getInt64(sp + 16);
254- const n = this.mem.getInt32(sp + 24, true);
255- fs.writeSync(fd, new Uint8Array(this._inst.exports.mem.buffer, p, n));
256- },
257-
258- // func resetMemoryDataView()
259- "runtime.resetMemoryDataView": (sp) => {
260- sp >>>= 0;
261- this.mem = new DataView(this._inst.exports.mem.buffer);
262- },
263-
264- // func nanotime1() int64
265- "runtime.nanotime1": (sp) => {
266- sp >>>= 0;
267- setInt64(sp + 8, (timeOrigin + performance.now()) * 1000000);
268- },
269-
270- // func walltime() (sec int64, nsec int32)
271- "runtime.walltime": (sp) => {
272- sp >>>= 0;
273- const msec = (new Date).getTime();
274- setInt64(sp + 8, msec / 1000);
275- this.mem.setInt32(sp + 16, (msec % 1000) * 1000000, true);
276- },
277-
278- // func scheduleTimeoutEvent(delay int64) int32
279- "runtime.scheduleTimeoutEvent": (sp) => {
280- sp >>>= 0;
281- const id = this._nextCallbackTimeoutID;
282- this._nextCallbackTimeoutID++;
283- this._scheduledTimeouts.set(id, setTimeout(
284- () => {
285- this._resume();
286- while (this._scheduledTimeouts.has(id)) {
287- // for some reason Go failed to register the timeout event, log and try again
288- // (temporary workaround for https://github.com/golang/go/issues/28975)
289- console.warn("scheduleTimeoutEvent: missed timeout event");
290- this._resume();
291- }
292- },
293- getInt64(sp + 8),
294- ));
295- this.mem.setInt32(sp + 16, id, true);
296- },
297-
298- // func clearTimeoutEvent(id int32)
299- "runtime.clearTimeoutEvent": (sp) => {
300- sp >>>= 0;
301- const id = this.mem.getInt32(sp + 8, true);
302- clearTimeout(this._scheduledTimeouts.get(id));
303- this._scheduledTimeouts.delete(id);
304- },
305-
306- // func getRandomData(r []byte)
307- "runtime.getRandomData": (sp) => {
308- sp >>>= 0;
309- crypto.getRandomValues(loadSlice(sp + 8));
310- },
311-
312- // func finalizeRef(v ref)
313- "syscall/js.finalizeRef": (sp) => {
314- sp >>>= 0;
315- const id = this.mem.getUint32(sp + 8, true);
316- this._goRefCounts[id]--;
317- if (this._goRefCounts[id] === 0) {
318- const v = this._values[id];
319- this._values[id] = null;
320- this._ids.delete(v);
321- this._idPool.push(id);
322- }
323- },
324-
325- // func stringVal(value string) ref
326- "syscall/js.stringVal": (sp) => {
327- sp >>>= 0;
328- storeValue(sp + 24, loadString(sp + 8));
329- },
330-
331- // func valueGet(v ref, p string) ref
332- "syscall/js.valueGet": (sp) => {
333- sp >>>= 0;
334- const result = Reflect.get(loadValue(sp + 8), loadString(sp + 16));
335- sp = this._inst.exports.getsp() >>> 0; // see comment above
336- storeValue(sp + 32, result);
337- },
338-
339- // func valueSet(v ref, p string, x ref)
340- "syscall/js.valueSet": (sp) => {
341- sp >>>= 0;
342- Reflect.set(loadValue(sp + 8), loadString(sp + 16), loadValue(sp + 32));
343- },
344-
345- // func valueDelete(v ref, p string)
346- "syscall/js.valueDelete": (sp) => {
347- sp >>>= 0;
348- Reflect.deleteProperty(loadValue(sp + 8), loadString(sp + 16));
349- },
350-
351- // func valueIndex(v ref, i int) ref
352- "syscall/js.valueIndex": (sp) => {
353- sp >>>= 0;
354- storeValue(sp + 24, Reflect.get(loadValue(sp + 8), getInt64(sp + 16)));
355- },
356-
357- // valueSetIndex(v ref, i int, x ref)
358- "syscall/js.valueSetIndex": (sp) => {
359- sp >>>= 0;
360- Reflect.set(loadValue(sp + 8), getInt64(sp + 16), loadValue(sp + 24));
361- },
362-
363- // func valueCall(v ref, m string, args []ref) (ref, bool)
364- "syscall/js.valueCall": (sp) => {
365- sp >>>= 0;
366- try {
367- const v = loadValue(sp + 8);
368- const m = Reflect.get(v, loadString(sp + 16));
369- const args = loadSliceOfValues(sp + 32);
370- const result = Reflect.apply(m, v, args);
371- sp = this._inst.exports.getsp() >>> 0; // see comment above
372- storeValue(sp + 56, result);
373- this.mem.setUint8(sp + 64, 1);
374- } catch (err) {
375- sp = this._inst.exports.getsp() >>> 0; // see comment above
376- storeValue(sp + 56, err);
377- this.mem.setUint8(sp + 64, 0);
378- }
379- },
380-
381- // func valueInvoke(v ref, args []ref) (ref, bool)
382- "syscall/js.valueInvoke": (sp) => {
383- sp >>>= 0;
384- try {
385- const v = loadValue(sp + 8);
386- const args = loadSliceOfValues(sp + 16);
387- const result = Reflect.apply(v, undefined, args);
388- sp = this._inst.exports.getsp() >>> 0; // see comment above
389- storeValue(sp + 40, result);
390- this.mem.setUint8(sp + 48, 1);
391- } catch (err) {
392- sp = this._inst.exports.getsp() >>> 0; // see comment above
393- storeValue(sp + 40, err);
394- this.mem.setUint8(sp + 48, 0);
395- }
396- },
397-
398- // func valueNew(v ref, args []ref) (ref, bool)
399- "syscall/js.valueNew": (sp) => {
400- sp >>>= 0;
401- try {
402- const v = loadValue(sp + 8);
403- const args = loadSliceOfValues(sp + 16);
404- const result = Reflect.construct(v, args);
405- sp = this._inst.exports.getsp() >>> 0; // see comment above
406- storeValue(sp + 40, result);
407- this.mem.setUint8(sp + 48, 1);
408- } catch (err) {
409- sp = this._inst.exports.getsp() >>> 0; // see comment above
410- storeValue(sp + 40, err);
411- this.mem.setUint8(sp + 48, 0);
412- }
413- },
414-
415- // func valueLength(v ref) int
416- "syscall/js.valueLength": (sp) => {
417- sp >>>= 0;
418- setInt64(sp + 16, parseInt(loadValue(sp + 8).length));
419- },
420-
421- // valuePrepareString(v ref) (ref, int)
422- "syscall/js.valuePrepareString": (sp) => {
423- sp >>>= 0;
424- const str = encoder.encode(String(loadValue(sp + 8)));
425- storeValue(sp + 16, str);
426- setInt64(sp + 24, str.length);
427- },
428-
429- // valueLoadString(v ref, b []byte)
430- "syscall/js.valueLoadString": (sp) => {
431- sp >>>= 0;
432- const str = loadValue(sp + 8);
433- loadSlice(sp + 16).set(str);
434- },
435-
436- // func valueInstanceOf(v ref, t ref) bool
437- "syscall/js.valueInstanceOf": (sp) => {
438- sp >>>= 0;
439- this.mem.setUint8(sp + 24, (loadValue(sp + 8) instanceof loadValue(sp + 16)) ? 1 : 0);
440- },
441-
442- // func copyBytesToGo(dst []byte, src ref) (int, bool)
443- "syscall/js.copyBytesToGo": (sp) => {
444- sp >>>= 0;
445- const dst = loadSlice(sp + 8);
446- const src = loadValue(sp + 32);
447- if (!(src instanceof Uint8Array || src instanceof Uint8ClampedArray)) {
448- this.mem.setUint8(sp + 48, 0);
449- return;
450- }
451- const toCopy = src.subarray(0, dst.length);
452- dst.set(toCopy);
453- setInt64(sp + 40, toCopy.length);
454- this.mem.setUint8(sp + 48, 1);
455- },
456-
457- // func copyBytesToJS(dst ref, src []byte) (int, bool)
458- "syscall/js.copyBytesToJS": (sp) => {
459- sp >>>= 0;
460- const dst = loadValue(sp + 8);
461- const src = loadSlice(sp + 16);
462- if (!(dst instanceof Uint8Array || dst instanceof Uint8ClampedArray)) {
463- this.mem.setUint8(sp + 48, 0);
464- return;
465- }
466- const toCopy = src.subarray(0, dst.length);
467- dst.set(toCopy);
468- setInt64(sp + 40, toCopy.length);
469- this.mem.setUint8(sp + 48, 1);
470- },
471-
472- "debug": (value) => {
473- console.log(value);
474- },
475- }
476- };
477- }
478-
479- async run(instance) {
480- if (!(instance instanceof WebAssembly.Instance)) {
481- throw new Error("Go.run: WebAssembly.Instance expected");
482- }
483- this._inst = instance;
484- this.mem = new DataView(this._inst.exports.mem.buffer);
485- this._values = [ // JS values that Go currently has references to, indexed by reference id
486- NaN,
487- 0,
488- null,
489- true,
490- false,
491- globalThis,
492- this,
493- ];
494- this._goRefCounts = new Array(this._values.length).fill(Infinity); // number of references that Go has to a JS value, indexed by reference id
495- this._ids = new Map([ // mapping from JS values to reference ids
496- [0, 1],
497- [null, 2],
498- [true, 3],
499- [false, 4],
500- [globalThis, 5],
501- [this, 6],
502- ]);
503- this._idPool = []; // unused ids that have been garbage collected
504- this.exited = false; // whether the Go program has exited
505-
506- // Pass command line arguments and environment variables to WebAssembly by writing them to the linear memory.
507- let offset = 4096;
508-
509- const strPtr = (str) => {
510- const ptr = offset;
511- const bytes = encoder.encode(str + "\0");
512- new Uint8Array(this.mem.buffer, offset, bytes.length).set(bytes);
513- offset += bytes.length;
514- if (offset % 8 !== 0) {
515- offset += 8 - (offset % 8);
516- }
517- return ptr;
518- };
519-
520- const argc = this.argv.length;
521-
522- const argvPtrs = [];
523- this.argv.forEach((arg) => {
524- argvPtrs.push(strPtr(arg));
525- });
526- argvPtrs.push(0);
527-
528- const keys = Object.keys(this.env).sort();
529- keys.forEach((key) => {
530- argvPtrs.push(strPtr(`${key}=${this.env[key]}`));
531- });
532- argvPtrs.push(0);
533-
534- const argv = offset;
535- argvPtrs.forEach((ptr) => {
536- this.mem.setUint32(offset, ptr, true);
537- this.mem.setUint32(offset + 4, 0, true);
538- offset += 8;
539- });
540-
541- // The linker guarantees global data starts from at least wasmMinDataAddr.
542- // Keep in sync with cmd/link/internal/ld/data.go:wasmMinDataAddr.
543- const wasmMinDataAddr = 4096 + 8192;
544- if (offset >= wasmMinDataAddr) {
545- throw new Error("total length of command line and environment variables exceeds limit");
546- }
547-
548- this._inst.exports.run(argc, argv);
549- if (this.exited) {
550- this._resolveExitPromise();
551- }
552- await this._exitPromise;
553- }
554-
555- _resume() {
556- if (this.exited) {
557- throw new Error("Go program has already exited");
558- }
559- this._inst.exports.resume();
560- if (this.exited) {
561- this._resolveExitPromise();
562- }
563- }
564-
565- _makeFuncWrapper(id) {
566- const go = this;
567- return function () {
568- const event = { id: id, this: this, args: arguments };
569- go._pendingEvent = event;
570- go._resume();
571- return event.result;
572- };
573- }
574- }
575-})();

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 8

Tags 42

↑↓ moveenter openesc close