feat: first working version with parameters
This commit is contained in:
@ -12,7 +12,6 @@
|
||||
if (registerIndex > $sizes.length) {
|
||||
$sizes = [...$sizes, "1fr"];
|
||||
}
|
||||
console.log("registering cell", registerIndex);
|
||||
return index;
|
||||
});
|
||||
|
||||
|
@ -1,5 +1,20 @@
|
||||
import { expect, test } from 'vitest'
|
||||
import { decode, encode } from './flat_tree'
|
||||
import { decode, encode, concat_encoded } from './flat_tree'
|
||||
|
||||
test("it correctly concats nested arrays", () => {
|
||||
|
||||
const input_a = encode([1, 2, 3]);
|
||||
const input_b = 2;
|
||||
const input_c = encode([4, 5, 6]);
|
||||
|
||||
const output = concat_encoded([input_a, input_b, input_c]);
|
||||
|
||||
const decoded = decode(output);
|
||||
|
||||
expect(decoded[0]).toEqual([1, 2, 3]);
|
||||
|
||||
|
||||
});
|
||||
|
||||
// Original test case
|
||||
test('it correctly decodes/encodes complex nested arrays', () => {
|
||||
@ -55,7 +70,7 @@ test('it correctly handles sequential nesting', () => {
|
||||
// If not, you can ignore or remove this test.
|
||||
test('it correctly handles arrays with mixed data types', () => {
|
||||
const input = [1, 'text', [true, [null, ['another text']]]];
|
||||
// @ts-ignore
|
||||
//@ts-ignore
|
||||
const decoded = decode(encode(input));
|
||||
expect(decoded).toEqual(input);
|
||||
});
|
||||
|
@ -1,5 +1,34 @@
|
||||
type SparseArray<T = number> = (T | T[] | SparseArray<T>)[];
|
||||
|
||||
export function concat_encoded(input: (number | number[])[]): number[] {
|
||||
|
||||
if (input.length === 1 && Array.isArray(input[0])) {
|
||||
return input[0]
|
||||
}
|
||||
|
||||
const result = [0, 1]; // opening bracket
|
||||
|
||||
let last_closing_bracket = 1;
|
||||
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
const item = input[i];
|
||||
if (Array.isArray(item)) {
|
||||
result.push(...item);
|
||||
if (item.length > 2) {
|
||||
if (item[item.length - 2] !== 1 && item[item.length - 1] !== 1) {
|
||||
result.push(1, 1); // add closing bracket if missing
|
||||
}
|
||||
}
|
||||
last_closing_bracket = result.length - 1;
|
||||
} else {
|
||||
result[last_closing_bracket]++;
|
||||
result.push(item);
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// Encodes a nested array into a flat array with bracket and distance notation
|
||||
export function encode(array: SparseArray): number[] {
|
||||
const encoded = [0, 0]; // Initialize encoded array with root bracket notation
|
||||
@ -16,7 +45,7 @@ export function encode(array: SparseArray): number[] {
|
||||
} else {
|
||||
// Recursively encode non-empty arrays
|
||||
const child = encode(item);
|
||||
encoded.push(...child, 1, 0); // Note: The trailing comma after 0 can be removed
|
||||
encoded.push(...child, 1, 0);
|
||||
}
|
||||
// Update missingBracketIndex to the position of the newly added bracket
|
||||
missingBracketIndex = encoded.length - 1;
|
||||
|
@ -19,7 +19,7 @@ const nodeTypes: NodeType[] = [
|
||||
"b": { type: "float" },
|
||||
},
|
||||
outputs: ["float"],
|
||||
execute: (op_type: number, a: number, b: number) => {
|
||||
execute: ([op_type, a, b]: number[]) => {
|
||||
switch (op_type) {
|
||||
case 0: return a + b;
|
||||
case 1: return a - b;
|
||||
@ -47,39 +47,49 @@ export class RemoteNodeRegistry implements NodeRegistry {
|
||||
|
||||
constructor(private url: string) { }
|
||||
|
||||
private async loadNode(id: string) {
|
||||
const nodeUrl = `${this.url}/n/${id}`;
|
||||
const response = await fetch(nodeUrl);
|
||||
const wasmResponse = await fetch(`${nodeUrl}/wasm`);
|
||||
const wrapperReponse = await fetch(`${nodeUrl}/wrapper`);
|
||||
if (!wrapperReponse.ok) {
|
||||
this.status = "error";
|
||||
throw new Error(`Failed to load node ${id}`);
|
||||
}
|
||||
|
||||
let wrapperCode = await wrapperReponse.text();
|
||||
wrapperCode = wrapperCode.replace("wasm = val;", `if(wasm) return;
|
||||
wasm = val;`);
|
||||
const wasmWrapper = await import(/*@vite-ignore*/`data:text/javascript;base64,${btoa(wrapperCode)}#${id}`);
|
||||
|
||||
const module = new WebAssembly.Module(await wasmResponse.arrayBuffer());
|
||||
const instance = new WebAssembly.Instance(module, { ["./index_bg.js"]: wasmWrapper });
|
||||
wasmWrapper.__wbg_set_wasm(instance.exports);
|
||||
|
||||
if (!response.ok) {
|
||||
this.status = "error";
|
||||
throw new Error(`Failed to load node ${id}`);
|
||||
} else {
|
||||
log.log("loaded node", id);
|
||||
}
|
||||
const node = await response.json();
|
||||
node.execute = wasmWrapper.execute;
|
||||
return node;
|
||||
}
|
||||
|
||||
async load(nodeIds: string[]) {
|
||||
const a = performance.now();
|
||||
|
||||
nodeIds.push("max/plantarium/random");
|
||||
nodeIds.push("max/plantarium/float");
|
||||
nodeIds.push("max/plantarium/output");
|
||||
nodeIds.push("max/plantarium/array");
|
||||
nodeIds.push("max/plantarium/sum");
|
||||
|
||||
for (const id of nodeIds) {
|
||||
const nodeUrl = `${this.url}/n/${id}`;
|
||||
const response = await fetch(nodeUrl);
|
||||
const wasmResponse = await fetch(`${nodeUrl}/wasm`);
|
||||
const wrapperReponse = await fetch(`${nodeUrl}/wrapper`);
|
||||
if (!wrapperReponse.ok) {
|
||||
this.status = "error";
|
||||
throw new Error(`Failed to load node ${id}`);
|
||||
}
|
||||
const nodes = await Promise.all(nodeIds.map(id => this.loadNode(id)));
|
||||
|
||||
let wrapperCode = await wrapperReponse.text();
|
||||
wrapperCode = wrapperCode.replace("wasm = val;", `if(wasm) return;
|
||||
wasm = val;`);
|
||||
const wasmWrapper = await import(/*@vite-ignore*/`data:text/javascript;base64,${btoa(wrapperCode)}`);
|
||||
|
||||
const module = new WebAssembly.Module(await wasmResponse.arrayBuffer());
|
||||
const instance = new WebAssembly.Instance(module, { ["./index_bg.js"]: wasmWrapper });
|
||||
wasmWrapper.__wbg_set_wasm(instance.exports);
|
||||
|
||||
if (!response.ok) {
|
||||
this.status = "error";
|
||||
throw new Error(`Failed to load node ${id}`);
|
||||
}
|
||||
const node = await response.json();
|
||||
node.execute = wasmWrapper.execute;
|
||||
this.nodes.set(id, node);
|
||||
for (const node of nodes) {
|
||||
this.nodes.set(node.id, node);
|
||||
}
|
||||
|
||||
const duration = performance.now() - a;
|
||||
|
@ -1,4 +1,6 @@
|
||||
import type { Graph, NodeRegistry, NodeType, RuntimeExecutor } from "@nodes/types";
|
||||
import { encodeFloat } from "./helpers/encode";
|
||||
import { concat_encoded, encode } from "./helpers/flat_tree";
|
||||
|
||||
|
||||
export class MemoryRuntimeExecutor implements RuntimeExecutor {
|
||||
@ -140,15 +142,21 @@ export class MemoryRuntimeExecutor implements RuntimeExecutor {
|
||||
// execute the node and store the result
|
||||
try {
|
||||
const node_inputs = Object.entries(inputs);
|
||||
const transformed_inputs = node_inputs.map(([key, value]) => {
|
||||
const input_type = node_type.inputs[key];
|
||||
if (input.type === "float") {
|
||||
return
|
||||
const transformed_inputs = node_inputs.map(([key, value]: [string, any]) => {
|
||||
const input_type = node_type.inputs?.[key]!;
|
||||
if (value instanceof Int32Array) {
|
||||
return [...value.slice(0, value.length)];
|
||||
}
|
||||
console.log(key, input_type);
|
||||
|
||||
if (input_type.type === "float") {
|
||||
return encode(encodeFloat(value as number));
|
||||
}
|
||||
return value;
|
||||
});
|
||||
console.log(`Executing node ${node_type.id || node.id}`, node_inputs);
|
||||
results[node.id] = node_type.execute(...Object.values(inputs)) as number;
|
||||
const _inputs = concat_encoded(transformed_inputs);
|
||||
// console.log(`Executing node ${node_type.id || node.id}`, { _inputs, inputs, node_type });
|
||||
results[node.id] = node_type.execute(_inputs) as number;
|
||||
// console.log("--> result", results[node.id]);
|
||||
} catch (e) {
|
||||
console.error(`Error executing node ${node_type.id || node.id}`, e);
|
||||
}
|
||||
@ -159,7 +167,6 @@ export class MemoryRuntimeExecutor implements RuntimeExecutor {
|
||||
// return the result of the parent of the output node
|
||||
const res = results[outputNode.id] as string
|
||||
|
||||
|
||||
return res;
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user