@openfluke/welvet 0.1.3 → 0.1.4
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 +286 -800
- package/dist/index.browser.d.ts +32 -0
- package/dist/index.browser.js +37 -0
- package/dist/index.d.ts +30 -30
- package/dist/index.js +34 -83
- package/dist/loader.browser.d.ts +5 -0
- package/dist/loader.browser.js +25 -0
- package/dist/loader.d.ts +5 -3
- package/dist/loader.js +25 -89
- package/dist/{loom.wasm → main.wasm} +0 -0
- package/dist/types.d.ts +91 -197
- package/dist/types.js +2 -10
- package/dist/wasm_exec.js +568 -658
- package/package.json +4 -2
- package/dist/env.d.ts +0 -3
- package/dist/env.js +0 -3
- package/dist/transformer.d.ts +0 -5
- package/dist/transformer.js +0 -127
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @openfluke/welvet - Browser Entry Point
|
|
3
|
+
*
|
|
4
|
+
* Browser-only build without Node.js dependencies
|
|
5
|
+
* Isomorphic wrapper that mirrors main.go WASM exports
|
|
6
|
+
*/
|
|
7
|
+
import { Network } from "./types.js";
|
|
8
|
+
import { loadLoomWASMBrowser } from "./loader.browser.js";
|
|
9
|
+
export * from "./types.js";
|
|
10
|
+
export { loadLoomWASMBrowser };
|
|
11
|
+
/**
|
|
12
|
+
* Initialize WASM for Browser environment
|
|
13
|
+
*/
|
|
14
|
+
export declare function initBrowser(): Promise<void>;
|
|
15
|
+
/**
|
|
16
|
+
* Initialize - alias for initBrowser in browser context
|
|
17
|
+
*/
|
|
18
|
+
export declare function init(): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Create a network from JSON config
|
|
21
|
+
* Wrapper around the global createLoomNetwork function exposed by WASM
|
|
22
|
+
*/
|
|
23
|
+
export declare function createNetwork(config: object | string): Network;
|
|
24
|
+
/**
|
|
25
|
+
* Default export with all functions
|
|
26
|
+
*/
|
|
27
|
+
declare const _default: {
|
|
28
|
+
init: typeof init;
|
|
29
|
+
initBrowser: typeof initBrowser;
|
|
30
|
+
createNetwork: typeof createNetwork;
|
|
31
|
+
};
|
|
32
|
+
export default _default;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @openfluke/welvet - Browser Entry Point
|
|
3
|
+
*
|
|
4
|
+
* Browser-only build without Node.js dependencies
|
|
5
|
+
* Isomorphic wrapper that mirrors main.go WASM exports
|
|
6
|
+
*/
|
|
7
|
+
import { loadLoomWASMBrowser } from "./loader.browser.js";
|
|
8
|
+
export * from "./types.js";
|
|
9
|
+
export { loadLoomWASMBrowser };
|
|
10
|
+
/**
|
|
11
|
+
* Initialize WASM for Browser environment
|
|
12
|
+
*/
|
|
13
|
+
export async function initBrowser() {
|
|
14
|
+
await loadLoomWASMBrowser();
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Initialize - alias for initBrowser in browser context
|
|
18
|
+
*/
|
|
19
|
+
export async function init() {
|
|
20
|
+
return initBrowser();
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Create a network from JSON config
|
|
24
|
+
* Wrapper around the global createLoomNetwork function exposed by WASM
|
|
25
|
+
*/
|
|
26
|
+
export function createNetwork(config) {
|
|
27
|
+
const jsonConfig = typeof config === 'string' ? config : JSON.stringify(config);
|
|
28
|
+
return createLoomNetwork(jsonConfig);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Default export with all functions
|
|
32
|
+
*/
|
|
33
|
+
export default {
|
|
34
|
+
init,
|
|
35
|
+
initBrowser,
|
|
36
|
+
createNetwork
|
|
37
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,33 +1,33 @@
|
|
|
1
|
-
import type { InitOptions, LoomAPI } from "./types.js";
|
|
2
1
|
/**
|
|
3
|
-
*
|
|
2
|
+
* @openfluke/welvet - Isomorphic WASM Wrapper
|
|
4
3
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
*
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
*
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
*
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
*
|
|
4
|
+
* Direct wrapper around Loom WASM that mirrors main.go exports exactly.
|
|
5
|
+
* Provides the same API in both Node.js and browser environments.
|
|
6
|
+
*/
|
|
7
|
+
import { Network } from "./types.js";
|
|
8
|
+
import { loadLoomWASM } from "./loader.js";
|
|
9
|
+
import { loadLoomWASMBrowser } from "./loader.browser.js";
|
|
10
|
+
export * from "./types.js";
|
|
11
|
+
export { loadLoomWASM, loadLoomWASMBrowser };
|
|
12
|
+
/**
|
|
13
|
+
* Initialize WASM for Node.js environment
|
|
14
|
+
*/
|
|
15
|
+
export declare function init(): Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* Initialize WASM for Browser environment
|
|
18
|
+
*/
|
|
19
|
+
export declare function initBrowser(): Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* Create a network from JSON config
|
|
22
|
+
* Wrapper around the global createLoomNetwork function exposed by WASM
|
|
23
|
+
*/
|
|
24
|
+
export declare function createNetwork(config: object | string): Network;
|
|
25
|
+
/**
|
|
26
|
+
* Default export with all functions
|
|
28
27
|
*/
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
28
|
+
declare const _default: {
|
|
29
|
+
init: typeof init;
|
|
30
|
+
initBrowser: typeof initBrowser;
|
|
31
|
+
createNetwork: typeof createNetwork;
|
|
32
|
+
};
|
|
33
|
+
export default _default;
|
package/dist/index.js
CHANGED
|
@@ -1,87 +1,38 @@
|
|
|
1
|
-
import { ensureGoRuntime, resolvePackagedWasmURL, instantiateGoWasm, } from "./loader.js";
|
|
2
|
-
// tiny helper that waits until WASM has placed symbols on globalThis
|
|
3
|
-
async function waitForExports(keys, timeoutMs = 5000) {
|
|
4
|
-
const t0 = performance.now();
|
|
5
|
-
for (;;) {
|
|
6
|
-
const ok = keys.every((k) => globalThis[k]);
|
|
7
|
-
if (ok)
|
|
8
|
-
return;
|
|
9
|
-
if (performance.now() - t0 > timeoutMs) {
|
|
10
|
-
throw new Error(`loom: timed out waiting for exports: ${keys.join(", ")}`);
|
|
11
|
-
}
|
|
12
|
-
await new Promise((r) => setTimeout(r, 10));
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
1
|
/**
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* @example
|
|
19
|
-
* ```typescript
|
|
20
|
-
* import { initLoom, ActivationType } from '@openfluke/loom';
|
|
21
|
-
*
|
|
22
|
-
* const loom = await initLoom();
|
|
23
|
-
*
|
|
24
|
-
* // Create a network: 784 → 392 → 10
|
|
25
|
-
* const network = loom.NewNetwork(784, 1, 1, 2);
|
|
26
|
-
*
|
|
27
|
-
* // Configure layers
|
|
28
|
-
* const layer0 = loom.InitDenseLayer(784, 392, ActivationType.ReLU);
|
|
29
|
-
* const layer1 = loom.InitDenseLayer(392, 10, ActivationType.Sigmoid);
|
|
2
|
+
* @openfluke/welvet - Isomorphic WASM Wrapper
|
|
30
3
|
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
*
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
*
|
|
40
|
-
* ```
|
|
4
|
+
* Direct wrapper around Loom WASM that mirrors main.go exports exactly.
|
|
5
|
+
* Provides the same API in both Node.js and browser environments.
|
|
6
|
+
*/
|
|
7
|
+
import { loadLoomWASM } from "./loader.js";
|
|
8
|
+
import { loadLoomWASMBrowser } from "./loader.browser.js";
|
|
9
|
+
export * from "./types.js";
|
|
10
|
+
export { loadLoomWASM, loadLoomWASMBrowser };
|
|
11
|
+
/**
|
|
12
|
+
* Initialize WASM for Node.js environment
|
|
41
13
|
*/
|
|
42
|
-
export async function
|
|
43
|
-
await
|
|
44
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
45
|
-
const go = new globalThis.Go();
|
|
46
|
-
const wasmUrl = await resolvePackagedWasmURL(opts.wasmUrl);
|
|
47
|
-
const instance = await instantiateGoWasm(go, wasmUrl);
|
|
48
|
-
// IMPORTANT: don't await this — it resolves when the Go program exits.
|
|
49
|
-
// Let it run; then poll for the exported symbols.
|
|
50
|
-
// no await:
|
|
51
|
-
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
52
|
-
Promise.resolve().then(() => go.run(instance));
|
|
53
|
-
// wait until your Go code has installed the globals
|
|
54
|
-
await waitForExports(["NewNetwork", "LoadModelFromString", "CallLayerInit"]);
|
|
55
|
-
const g = globalThis;
|
|
56
|
-
// Helper function to call layer init functions from the registry
|
|
57
|
-
const callLayerInit = (funcName, ...params) => {
|
|
58
|
-
return g.CallLayerInit(funcName, JSON.stringify(params));
|
|
59
|
-
};
|
|
60
|
-
const api = {
|
|
61
|
-
NewNetwork: g.NewNetwork,
|
|
62
|
-
LoadModelFromString: g.LoadModelFromString,
|
|
63
|
-
CallLayerInit: g.CallLayerInit, // Direct access to registry-based layer init
|
|
64
|
-
// Layer initialization functions using CallLayerInit (registry-based)
|
|
65
|
-
InitDenseLayer: (inputSize, outputSize, activation) => {
|
|
66
|
-
return callLayerInit("InitDenseLayer", inputSize, outputSize, activation);
|
|
67
|
-
},
|
|
68
|
-
InitConv2DLayer: (inChannels, outChannels, kernelSize, stride, padding, inputH, inputW, activation) => {
|
|
69
|
-
return callLayerInit("InitConv2DLayer", inChannels, outChannels, kernelSize, stride, padding, inputH, inputW, activation);
|
|
70
|
-
},
|
|
71
|
-
InitMultiHeadAttentionLayer: (dModel, numHeads, seqLength, activation) => {
|
|
72
|
-
return callLayerInit("InitMultiHeadAttentionLayer", dModel, numHeads, seqLength, activation);
|
|
73
|
-
},
|
|
74
|
-
InitRNNLayer: (inputSize, hiddenSize, seqLength, outputSize) => {
|
|
75
|
-
return callLayerInit("InitRNNLayer", inputSize, hiddenSize, seqLength, outputSize);
|
|
76
|
-
},
|
|
77
|
-
InitLSTMLayer: (inputSize, hiddenSize, seqLength, outputSize) => {
|
|
78
|
-
return callLayerInit("InitLSTMLayer", inputSize, hiddenSize, seqLength, outputSize);
|
|
79
|
-
},
|
|
80
|
-
};
|
|
81
|
-
if (!api.NewNetwork) {
|
|
82
|
-
throw new Error("loom: NewNetwork not found after WASM init");
|
|
83
|
-
}
|
|
84
|
-
return api;
|
|
14
|
+
export async function init() {
|
|
15
|
+
await loadLoomWASM();
|
|
85
16
|
}
|
|
86
|
-
|
|
87
|
-
|
|
17
|
+
/**
|
|
18
|
+
* Initialize WASM for Browser environment
|
|
19
|
+
*/
|
|
20
|
+
export async function initBrowser() {
|
|
21
|
+
await loadLoomWASMBrowser();
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Create a network from JSON config
|
|
25
|
+
* Wrapper around the global createLoomNetwork function exposed by WASM
|
|
26
|
+
*/
|
|
27
|
+
export function createNetwork(config) {
|
|
28
|
+
const jsonConfig = typeof config === 'string' ? config : JSON.stringify(config);
|
|
29
|
+
return createLoomNetwork(jsonConfig);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Default export with all functions
|
|
33
|
+
*/
|
|
34
|
+
export default {
|
|
35
|
+
init,
|
|
36
|
+
initBrowser,
|
|
37
|
+
createNetwork
|
|
38
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LOOM WASM Browser Loader
|
|
3
|
+
* Browser-only version without Node.js dependencies
|
|
4
|
+
*/
|
|
5
|
+
export async function loadLoomWASMBrowser() {
|
|
6
|
+
// For browser environments - load wasm_exec.js first if not already loaded
|
|
7
|
+
if (typeof globalThis.Go === "undefined") {
|
|
8
|
+
// Load wasm_exec.js dynamically from /dist/
|
|
9
|
+
const script = document.createElement("script");
|
|
10
|
+
script.src = "/dist/wasm_exec.js";
|
|
11
|
+
await new Promise((resolve, reject) => {
|
|
12
|
+
script.onload = () => resolve();
|
|
13
|
+
script.onerror = () => reject(new Error("Failed to load wasm_exec.js"));
|
|
14
|
+
document.head.appendChild(script);
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
const response = await fetch("/dist/main.wasm");
|
|
18
|
+
const wasmBuffer = await response.arrayBuffer();
|
|
19
|
+
// @ts-ignore - Go is defined by wasm_exec.js
|
|
20
|
+
const go = new Go();
|
|
21
|
+
const { instance } = await WebAssembly.instantiate(wasmBuffer, go.importObject);
|
|
22
|
+
go.run(instance);
|
|
23
|
+
// Wait for initialization
|
|
24
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
25
|
+
}
|
package/dist/loader.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
/**
|
|
2
|
+
* LOOM WASM Loader
|
|
3
|
+
* Loads and initializes the LOOM WebAssembly module (Node.js only)
|
|
4
|
+
*/
|
|
5
|
+
export declare function loadLoomWASM(): Promise<void>;
|
package/dist/loader.js
CHANGED
|
@@ -1,90 +1,26 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
|
-
const url = new URL("./wasm_exec.js", import.meta.url);
|
|
29
|
-
const res = await fetch(url);
|
|
30
|
-
if (!res.ok)
|
|
31
|
-
throw new Error(`Failed to fetch wasm_exec.js (${res.status} ${res.statusText}) from ${url}`);
|
|
32
|
-
const jsText = await res.text();
|
|
33
|
-
new Function(jsText)();
|
|
34
|
-
goRuntimeInjected = true;
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
const { readFile } = await import("node:fs/promises");
|
|
38
|
-
const { fileURLToPath } = await import("node:url");
|
|
39
|
-
const wasmExecUrl = new URL("./wasm_exec.js", import.meta.url);
|
|
40
|
-
const filePath = fileURLToPath(wasmExecUrl);
|
|
41
|
-
const jsText = await readFile(filePath, "utf8");
|
|
42
|
-
new Function(jsText)();
|
|
43
|
-
goRuntimeInjected = true;
|
|
44
|
-
}
|
|
45
|
-
export async function resolvePackagedWasmURL(override) {
|
|
46
|
-
if (override)
|
|
47
|
-
return override;
|
|
48
|
-
if (isBrowser) {
|
|
49
|
-
if (!wasmUrlBundled)
|
|
50
|
-
await tryLoadBundlerAssets();
|
|
51
|
-
if (wasmUrlBundled)
|
|
52
|
-
return wasmUrlBundled;
|
|
53
|
-
return new URL("./loom.wasm", import.meta.url);
|
|
54
|
-
}
|
|
55
|
-
return new URL("./loom.wasm", import.meta.url);
|
|
56
|
-
}
|
|
57
|
-
export async function instantiateGoWasm(go, wasmUrl) {
|
|
58
|
-
const asString = typeof wasmUrl === "string" ? wasmUrl : wasmUrl.toString();
|
|
59
|
-
if (isBrowser) {
|
|
60
|
-
if (typeof WebAssembly.instantiateStreaming === "function") {
|
|
61
|
-
const res = await fetch(asString);
|
|
62
|
-
try {
|
|
63
|
-
const { instance } = await WebAssembly.instantiateStreaming(res, go.importObject);
|
|
64
|
-
return instance;
|
|
65
|
-
}
|
|
66
|
-
catch {
|
|
67
|
-
const buf = await res.arrayBuffer();
|
|
68
|
-
const result = (await WebAssembly.instantiate(buf, go.importObject));
|
|
69
|
-
const instance = result.instance ?? result;
|
|
70
|
-
return instance;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
else {
|
|
74
|
-
const res = await fetch(asString);
|
|
75
|
-
const buf = await res.arrayBuffer();
|
|
76
|
-
const result = (await WebAssembly.instantiate(buf, go.importObject));
|
|
77
|
-
const instance = result.instance ?? result;
|
|
78
|
-
return instance;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
// Node/Bun
|
|
82
|
-
const { readFile } = await import("node:fs/promises");
|
|
83
|
-
const { fileURLToPath } = await import("node:url");
|
|
84
|
-
const url = typeof wasmUrl === "string" ? new URL(wasmUrl, import.meta.url) : wasmUrl;
|
|
85
|
-
const filePath = fileURLToPath(url);
|
|
86
|
-
const buf = await readFile(filePath);
|
|
87
|
-
const result = (await WebAssembly.instantiate(buf, go.importObject));
|
|
88
|
-
const instance = result.instance ?? result;
|
|
89
|
-
return instance;
|
|
1
|
+
/**
|
|
2
|
+
* LOOM WASM Loader
|
|
3
|
+
* Loads and initializes the LOOM WebAssembly module (Node.js only)
|
|
4
|
+
*/
|
|
5
|
+
import { readFileSync } from "fs";
|
|
6
|
+
import { fileURLToPath } from "url";
|
|
7
|
+
import { dirname, join } from "path";
|
|
8
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
9
|
+
const __dirname = dirname(__filename);
|
|
10
|
+
export async function loadLoomWASM() {
|
|
11
|
+
// Load wasm_exec.js
|
|
12
|
+
const wasmExecPath = join(__dirname, "../assets/wasm_exec.js");
|
|
13
|
+
const wasmExecCode = readFileSync(wasmExecPath, "utf-8");
|
|
14
|
+
// Execute wasm_exec.js to get the Go runtime
|
|
15
|
+
eval(wasmExecCode);
|
|
16
|
+
// Load main.wasm
|
|
17
|
+
const wasmPath = join(__dirname, "../assets/main.wasm");
|
|
18
|
+
const wasmBuffer = readFileSync(wasmPath);
|
|
19
|
+
// @ts-ignore - Go is defined by wasm_exec.js
|
|
20
|
+
const go = new Go();
|
|
21
|
+
const { instance } = await WebAssembly.instantiate(wasmBuffer, go.importObject);
|
|
22
|
+
// Run the Go WASM module
|
|
23
|
+
go.run(instance);
|
|
24
|
+
// Wait a bit for initialization
|
|
25
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
90
26
|
}
|
|
Binary file
|