fix: 120 type errors
All checks were successful
Deploy to GitHub Pages / build_site (push) Successful in 2m47s
All checks were successful
Deploy to GitHub Pages / build_site (push) Successful in 2m47s
This commit is contained in:
@@ -52,7 +52,7 @@
|
|||||||
|
|
||||||
if (event.key === "Enter") {
|
if (event.key === "Enter") {
|
||||||
if (activeNodeId && position) {
|
if (activeNodeId && position) {
|
||||||
graph.createNode({ type: activeNodeId, position });
|
graph.createNode({ type: activeNodeId, position, props: {} });
|
||||||
position = null;
|
position = null;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
<script lang="ts">
|
|
||||||
import type { Hst } from "@histoire/plugin-svelte";
|
|
||||||
export let Hst: Hst;
|
|
||||||
import Background from "./Background.svelte";
|
|
||||||
import { Canvas } from "@threlte/core";
|
|
||||||
import Camera from "../Camera.svelte";
|
|
||||||
let width = globalThis.innerWidth || 100;
|
|
||||||
let height = globalThis.innerHeight || 100;
|
|
||||||
|
|
||||||
let cameraPosition: [number, number, number] = [0, 1, 0];
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<svelte:window bind:innerWidth={width} bind:innerHeight={height} />
|
|
||||||
|
|
||||||
<Hst.Story>
|
|
||||||
<Canvas shadows={false}>
|
|
||||||
<Camera bind:position={cameraPosition} />
|
|
||||||
|
|
||||||
<Background {cameraPosition} {width} {height} />
|
|
||||||
</Canvas>
|
|
||||||
</Hst.Story>
|
|
||||||
@@ -11,7 +11,7 @@ import { fastHashString } from "@nodes/utils";
|
|||||||
import { SvelteMap } from "svelte/reactivity";
|
import { SvelteMap } from "svelte/reactivity";
|
||||||
import EventEmitter from "./helpers/EventEmitter";
|
import EventEmitter from "./helpers/EventEmitter";
|
||||||
import { createLogger } from "./helpers/index";
|
import { createLogger } from "./helpers/index";
|
||||||
import throttle from "./helpers/throttle";
|
import throttle from "$lib/helpers/throttle";
|
||||||
import { HistoryManager } from "./history-manager";
|
import { HistoryManager } from "./history-manager";
|
||||||
|
|
||||||
const logger = createLogger("graph-manager");
|
const logger = createLogger("graph-manager");
|
||||||
@@ -24,7 +24,7 @@ const clone =
|
|||||||
|
|
||||||
function areSocketsCompatible(
|
function areSocketsCompatible(
|
||||||
output: string | undefined,
|
output: string | undefined,
|
||||||
inputs: string | string[] | undefined,
|
inputs: string | (string | undefined)[] | undefined,
|
||||||
) {
|
) {
|
||||||
if (Array.isArray(inputs) && output) {
|
if (Array.isArray(inputs) && output) {
|
||||||
return inputs.includes(output);
|
return inputs.includes(output);
|
||||||
@@ -99,7 +99,6 @@ export class GraphManager extends EventEmitter<{
|
|||||||
|
|
||||||
private lastSettingsHash = 0;
|
private lastSettingsHash = 0;
|
||||||
setSettings(settings: Record<string, unknown>) {
|
setSettings(settings: Record<string, unknown>) {
|
||||||
console.log("GraphManager.setSettings", settings);
|
|
||||||
let hash = fastHashString(JSON.stringify(settings));
|
let hash = fastHashString(JSON.stringify(settings));
|
||||||
if (hash === this.lastSettingsHash) return;
|
if (hash === this.lastSettingsHash) return;
|
||||||
this.lastSettingsHash = hash;
|
this.lastSettingsHash = hash;
|
||||||
@@ -154,7 +153,7 @@ export class GraphManager extends EventEmitter<{
|
|||||||
|
|
||||||
private _init(graph: Graph) {
|
private _init(graph: Graph) {
|
||||||
const nodes = new Map(
|
const nodes = new Map(
|
||||||
graph.nodes.map((node) => {
|
graph.nodes.map((node: Node) => {
|
||||||
const nodeType = this.registry.getNode(node.type);
|
const nodeType = this.registry.getNode(node.type);
|
||||||
if (nodeType) {
|
if (nodeType) {
|
||||||
node.tmp = {
|
node.tmp = {
|
||||||
|
|||||||
@@ -23,8 +23,6 @@
|
|||||||
invalidate();
|
invalidate();
|
||||||
});
|
});
|
||||||
|
|
||||||
$effect(() => console.log({ nodes }));
|
|
||||||
|
|
||||||
const graphState = getGraphState();
|
const graphState = getGraphState();
|
||||||
|
|
||||||
const isNodeInView = getContext<(n: NodeType) => boolean>("isNodeInView");
|
const isNodeInView = getContext<(n: NodeType) => boolean>("isNodeInView");
|
||||||
@@ -50,8 +48,6 @@
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
const nodeArray = $derived(Array.from(nodes.values()));
|
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
for (const node of nodes.values()) {
|
for (const node of nodes.values()) {
|
||||||
if (node?.tmp?.ref) {
|
if (node?.tmp?.ref) {
|
||||||
@@ -86,9 +82,9 @@
|
|||||||
style:transform={`scale(${cameraPosition[2] * 0.1})`}
|
style:transform={`scale(${cameraPosition[2] * 0.1})`}
|
||||||
class:hovering-sockets={graphState.activeSocket}
|
class:hovering-sockets={graphState.activeSocket}
|
||||||
>
|
>
|
||||||
{#each nodeArray as node, i (node.id)}
|
{#each nodes.values() as node (node.id)}
|
||||||
<Node
|
<Node
|
||||||
bind:node={nodeArray[i]}
|
{node}
|
||||||
inView={cameraPosition && isNodeInView(node)}
|
inView={cameraPosition && isNodeInView(node)}
|
||||||
z={cameraPosition[2]}
|
z={cameraPosition[2]}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
import throttle from './throttle.js';
|
import throttle from "$lib/helpers/throttle";
|
||||||
|
|
||||||
type EventMap = Record<string, unknown>;
|
type EventMap = Record<string, unknown>;
|
||||||
type EventKey<T extends EventMap> = string & keyof T;
|
type EventKey<T extends EventMap> = string & keyof T;
|
||||||
type EventReceiver<T> = (params: T, stuff?: Record<string, unknown>) => unknown;
|
type EventReceiver<T> = (params: T, stuff?: Record<string, unknown>) => unknown;
|
||||||
|
|
||||||
|
export default class EventEmitter<
|
||||||
export default class EventEmitter<T extends EventMap = { [key: string]: unknown }> {
|
T extends EventMap = { [key: string]: unknown },
|
||||||
|
> {
|
||||||
index = 0;
|
index = 0;
|
||||||
public eventMap: T = {} as T;
|
public eventMap: T = {} as T;
|
||||||
constructor() {
|
constructor() {}
|
||||||
}
|
|
||||||
|
|
||||||
private cbs: { [key: string]: ((data?: unknown) => unknown)[] } = {};
|
private cbs: { [key: string]: ((data?: unknown) => unknown)[] } = {};
|
||||||
private cbsOnce: { [key: string]: ((data?: unknown) => unknown)[] } = {};
|
private cbsOnce: { [key: string]: ((data?: unknown) => unknown)[] } = {};
|
||||||
@@ -29,7 +29,11 @@ export default class EventEmitter<T extends EventMap = { [key: string]: unknown
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public on<K extends EventKey<T>>(event: K, cb: EventReceiver<T[K]>, throttleTimer = 0) {
|
public on<K extends EventKey<T>>(
|
||||||
|
event: K,
|
||||||
|
cb: EventReceiver<T[K]>,
|
||||||
|
throttleTimer = 0,
|
||||||
|
) {
|
||||||
if (throttleTimer > 0) cb = throttle(cb, throttleTimer);
|
if (throttleTimer > 0) cb = throttle(cb, throttleTimer);
|
||||||
const cbs = Object.assign(this.cbs, {
|
const cbs = Object.assign(this.cbs, {
|
||||||
[event]: [...(this.cbs[event] || []), cb],
|
[event]: [...(this.cbs[event] || []), cb],
|
||||||
@@ -38,7 +42,7 @@ export default class EventEmitter<T extends EventMap = { [key: string]: unknown
|
|||||||
|
|
||||||
// console.log('New EventEmitter ', this.constructor.name);
|
// console.log('New EventEmitter ', this.constructor.name);
|
||||||
return () => {
|
return () => {
|
||||||
cbs[event]?.splice(cbs[event].indexOf(cb), 1);
|
this.cbs[event]?.splice(cbs[event].indexOf(cb), 1);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,10 +52,17 @@ export default class EventEmitter<T extends EventMap = { [key: string]: unknown
|
|||||||
* @param {function} cb Listener, gets called everytime the event is emitted
|
* @param {function} cb Listener, gets called everytime the event is emitted
|
||||||
* @returns {function} Returns a function which removes the listener when called
|
* @returns {function} Returns a function which removes the listener when called
|
||||||
*/
|
*/
|
||||||
public once<K extends EventKey<T>>(event: K, cb: EventReceiver<T[K]>): () => void {
|
public once<K extends EventKey<T>>(
|
||||||
this.cbsOnce[event] = [...(this.cbsOnce[event] || []), cb];
|
event: K,
|
||||||
|
cb: EventReceiver<T[K]>,
|
||||||
|
): () => void {
|
||||||
|
const cbsOnce = Object.assign(this.cbsOnce, {
|
||||||
|
[event]: [...(this.cbsOnce[event] || []), cb],
|
||||||
|
});
|
||||||
|
this.cbsOnce = cbsOnce;
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
this.cbsOnce[event].splice(this.cbsOnce[event].indexOf(cb), 1);
|
cbsOnce[event]?.splice(cbsOnce[event].indexOf(cb), 1);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
export default <R, A extends any[]>(
|
|
||||||
fn: (...args: A) => R,
|
|
||||||
delay: number
|
|
||||||
): ((...args: A) => R) => {
|
|
||||||
let wait = false;
|
|
||||||
|
|
||||||
return (...args: A) => {
|
|
||||||
if (wait) return undefined;
|
|
||||||
|
|
||||||
const val = fn(...args);
|
|
||||||
|
|
||||||
wait = true;
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
wait = false;
|
|
||||||
}, delay);
|
|
||||||
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -2,23 +2,22 @@ import { create, type Delta } from "jsondiffpatch";
|
|||||||
import type { Graph } from "@nodes/types";
|
import type { Graph } from "@nodes/types";
|
||||||
import { createLogger, clone } from "./helpers/index.js";
|
import { createLogger, clone } from "./helpers/index.js";
|
||||||
|
|
||||||
|
|
||||||
const diff = create({
|
const diff = create({
|
||||||
objectHash: function (obj, index) {
|
objectHash: function (obj, index) {
|
||||||
if (obj === null) return obj;
|
if (obj === null) return obj;
|
||||||
if ("id" in obj) return obj.id;
|
if ("id" in obj) return obj.id as string;
|
||||||
|
if ("_id" in obj) return obj._id as string;
|
||||||
if (Array.isArray(obj)) {
|
if (Array.isArray(obj)) {
|
||||||
return obj.join("-")
|
return obj.join("-");
|
||||||
}
|
}
|
||||||
return obj?.id || obj._id || '$$index:' + index;
|
return "$$index:" + index;
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
const log = createLogger("history")
|
const log = createLogger("history");
|
||||||
log.mute();
|
log.mute();
|
||||||
|
|
||||||
export class HistoryManager {
|
export class HistoryManager {
|
||||||
|
|
||||||
index: number = -1;
|
index: number = -1;
|
||||||
history: Delta[] = [];
|
history: Delta[] = [];
|
||||||
private initialState: Graph | undefined;
|
private initialState: Graph | undefined;
|
||||||
@@ -27,26 +26,25 @@ export class HistoryManager {
|
|||||||
private opts = {
|
private opts = {
|
||||||
debounce: 400,
|
debounce: 400,
|
||||||
maxHistory: 100,
|
maxHistory: 100,
|
||||||
}
|
};
|
||||||
|
|
||||||
constructor({ maxHistory = 100, debounce = 100 } = {}) {
|
constructor({ maxHistory = 100, debounce = 100 } = {}) {
|
||||||
this.history = [];
|
this.history = [];
|
||||||
this.index = -1;
|
this.index = -1;
|
||||||
this.opts.debounce = debounce;
|
this.opts.debounce = debounce;
|
||||||
this.opts.maxHistory = maxHistory;
|
this.opts.maxHistory = maxHistory;
|
||||||
globalThis["_history"] = this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
save(state: Graph) {
|
save(state: Graph) {
|
||||||
if (!this.state) {
|
if (!this.state) {
|
||||||
this.state = clone(state);
|
this.state = clone(state);
|
||||||
this.initialState = this.state;
|
this.initialState = this.state;
|
||||||
log.log("initial state saved")
|
log.log("initial state saved");
|
||||||
} else {
|
} else {
|
||||||
const newState = state;
|
const newState = state;
|
||||||
const delta = diff.diff(this.state, newState);
|
const delta = diff.diff(this.state, newState);
|
||||||
if (delta) {
|
if (delta) {
|
||||||
log.log("saving state")
|
log.log("saving state");
|
||||||
// Add the delta to history
|
// Add the delta to history
|
||||||
if (this.index < this.history.length - 1) {
|
if (this.index < this.history.length - 1) {
|
||||||
// Clear the history after the current index if new changes are made
|
// Clear the history after the current index if new changes are made
|
||||||
@@ -62,7 +60,7 @@ export class HistoryManager {
|
|||||||
}
|
}
|
||||||
this.state = newState;
|
this.state = newState;
|
||||||
} else {
|
} else {
|
||||||
log.log("no changes")
|
log.log("no changes");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -76,7 +74,7 @@ export class HistoryManager {
|
|||||||
|
|
||||||
undo() {
|
undo() {
|
||||||
if (this.index === -1 && this.initialState) {
|
if (this.index === -1 && this.initialState) {
|
||||||
log.log("reached start, loading initial state")
|
log.log("reached start, loading initial state");
|
||||||
return clone(this.initialState);
|
return clone(this.initialState);
|
||||||
} else {
|
} else {
|
||||||
const delta = this.history[this.index];
|
const delta = this.history[this.index];
|
||||||
@@ -96,7 +94,7 @@ export class HistoryManager {
|
|||||||
this.state = nextState;
|
this.state = nextState;
|
||||||
return clone(nextState);
|
return clone(nextState);
|
||||||
} else {
|
} else {
|
||||||
log.log("reached end")
|
log.log("reached end");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,6 +41,7 @@
|
|||||||
const height = getNodeHeight?.(node.type);
|
const height = getNodeHeight?.(node.type);
|
||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
|
if (!node?.tmp) node.tmp = {};
|
||||||
node.tmp.mesh = meshRef;
|
node.tmp.mesh = meshRef;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -27,9 +27,7 @@
|
|||||||
const zOffset = (node.tmp?.random || 0) * 0.5;
|
const zOffset = (node.tmp?.random || 0) * 0.5;
|
||||||
const zLimit = 2 - zOffset;
|
const zLimit = 2 - zOffset;
|
||||||
|
|
||||||
const type = node?.tmp?.type;
|
const parameters = Object.entries(node?.tmp?.type?.inputs || {}).filter(
|
||||||
|
|
||||||
const parameters = Object.entries(type?.inputs || {}).filter(
|
|
||||||
(p) =>
|
(p) =>
|
||||||
p[1].type !== "seed" && !("setting" in p[1]) && p[1]?.hidden !== true,
|
p[1].type !== "seed" && !("setting" in p[1]) && p[1]?.hidden !== true,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
const {
|
const {
|
||||||
node,
|
node = $bindable(),
|
||||||
input,
|
input,
|
||||||
id,
|
id,
|
||||||
elementId = `input-${Math.random().toString(36).substring(7)}`,
|
elementId = `input-${Math.random().toString(36).substring(7)}`,
|
||||||
|
|||||||
@@ -82,7 +82,7 @@
|
|||||||
class:disabled={!graphState?.possibleSocketIds.has(socketId)}
|
class:disabled={!graphState?.possibleSocketIds.has(socketId)}
|
||||||
>
|
>
|
||||||
{#key id && graphId}
|
{#key id && graphId}
|
||||||
<div class="content" class:disabled={graph.inputSockets?.has(socketId)}>
|
<div class="content" class:disabled={graph?.inputSockets?.has(socketId)}>
|
||||||
{#if inputType.label !== ""}
|
{#if inputType.label !== ""}
|
||||||
<label for={elementId}>{input.label || id}</label>
|
<label for={elementId}>{input.label || id}</label>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -7,8 +7,6 @@
|
|||||||
|
|
||||||
const { children } = $props();
|
const { children } = $props();
|
||||||
|
|
||||||
console.log("RowChildren", children);
|
|
||||||
|
|
||||||
let registerIndex = 0;
|
let registerIndex = 0;
|
||||||
setContext("registerCell", function () {
|
setContext("registerCell", function () {
|
||||||
let index = registerIndex;
|
let index = registerIndex;
|
||||||
|
|||||||
@@ -1,20 +1,19 @@
|
|||||||
export default <R, A extends any[]>(
|
export default <T extends unknown[]>(
|
||||||
fn: (...args: A) => R,
|
callback: (...args: T) => void,
|
||||||
delay: number
|
delay: number,
|
||||||
): ((...args: A) => R) => {
|
) => {
|
||||||
let wait = false;
|
let isWaiting = false;
|
||||||
|
|
||||||
return (...args: A) => {
|
return (...args: T) => {
|
||||||
if (wait) return undefined;
|
if (isWaiting) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const val = fn(...args);
|
callback(...args);
|
||||||
|
isWaiting = true;
|
||||||
wait = true;
|
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
wait = false;
|
isWaiting = false;
|
||||||
}, delay);
|
}, delay);
|
||||||
|
};
|
||||||
return val;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { createWasmWrapper } from "@nodes/utils"
|
import { createWasmWrapper } from "@nodes/utils";
|
||||||
import fs from "fs/promises"
|
import fs from "fs/promises";
|
||||||
import path from "path"
|
import path from "path";
|
||||||
|
|
||||||
export async function getWasm(id: `${string}/${string}/${string}`) {
|
export async function getWasm(id: `${string}/${string}/${string}`) {
|
||||||
const filePath = path.resolve(`../nodes/${id}/pkg/index_bg.wasm`);
|
const filePath = path.resolve(`../nodes/${id}/pkg/index_bg.wasm`);
|
||||||
@@ -8,17 +8,15 @@ export async function getWasm(id: `${string}/${string}/${string}`) {
|
|||||||
try {
|
try {
|
||||||
await fs.access(filePath);
|
await fs.access(filePath);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return null
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const file = await fs.readFile(filePath);
|
const file = await fs.readFile(filePath);
|
||||||
|
|
||||||
return new Uint8Array(file);
|
return new Uint8Array(file);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getNodeWasm(id: `${string}/${string}/${string}`) {
|
export async function getNodeWasm(id: `${string}/${string}/${string}`) {
|
||||||
|
|
||||||
const wasmBytes = await getWasm(id);
|
const wasmBytes = await getWasm(id);
|
||||||
if (!wasmBytes) return null;
|
if (!wasmBytes) return null;
|
||||||
|
|
||||||
@@ -27,9 +25,7 @@ export async function getNodeWasm(id: `${string}/${string}/${string}`) {
|
|||||||
return wrapper;
|
return wrapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export async function getNode(id: `${string}/${string}/${string}`) {
|
export async function getNode(id: `${string}/${string}/${string}`) {
|
||||||
|
|
||||||
const wrapper = await getNodeWasm(id);
|
const wrapper = await getNodeWasm(id);
|
||||||
|
|
||||||
const definition = wrapper?.get_definition?.();
|
const definition = wrapper?.get_definition?.();
|
||||||
@@ -37,18 +33,17 @@ export async function getNode(id: `${string}/${string}/${string}`) {
|
|||||||
if (!definition) return null;
|
if (!definition) return null;
|
||||||
|
|
||||||
return definition;
|
return definition;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getCollectionNodes(userId: `${string}/${string}`) {
|
export async function getCollectionNodes(userId: `${string}/${string}`) {
|
||||||
const nodes = await fs.readdir(path.resolve(`../nodes/${userId}`));
|
const nodes = await fs.readdir(path.resolve(`../nodes/${userId}`));
|
||||||
return nodes
|
return nodes
|
||||||
.filter(n => n !== "pkg" && n !== ".template")
|
.filter((n) => n !== "pkg" && n !== ".template")
|
||||||
.map(n => {
|
.map((n) => {
|
||||||
return {
|
return {
|
||||||
id: `${userId}/${n}`,
|
id: `${userId}/${n}`,
|
||||||
}
|
};
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getCollection(userId: `${string}/${string}`) {
|
export async function getCollection(userId: `${string}/${string}`) {
|
||||||
@@ -56,36 +51,40 @@ export async function getCollection(userId: `${string}/${string}`) {
|
|||||||
return {
|
return {
|
||||||
id: userId,
|
id: userId,
|
||||||
nodes,
|
nodes,
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getUserCollections(userId: string) {
|
export async function getUserCollections(userId: string) {
|
||||||
const collections = await fs.readdir(path.resolve(`../nodes/${userId}`));
|
const collections = await fs.readdir(path.resolve(`../nodes/${userId}`));
|
||||||
return Promise.all(collections.map(async n => {
|
return Promise.all(
|
||||||
|
collections.map(async (n) => {
|
||||||
const nodes = await getCollectionNodes(`${userId}/${n}`);
|
const nodes = await getCollectionNodes(`${userId}/${n}`);
|
||||||
return {
|
return {
|
||||||
id: `${userId}/${n}`,
|
id: `${userId}/${n}`,
|
||||||
nodes,
|
nodes,
|
||||||
}
|
};
|
||||||
}));
|
}),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getUser(userId: string) {
|
export async function getUser(userId: string) {
|
||||||
const collections = await getUserCollections(userId);
|
const collections = await getUserCollections(userId);
|
||||||
return {
|
return {
|
||||||
id: userId,
|
id: userId,
|
||||||
collections
|
collections,
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getUsers() {
|
export async function getUsers() {
|
||||||
const nodes = await fs.readdir(path.resolve("../nodes"));
|
const nodes = await fs.readdir(path.resolve("../nodes"));
|
||||||
const users = await Promise.all(nodes.map(async n => {
|
const users = await Promise.all(
|
||||||
|
nodes.map(async (n) => {
|
||||||
const collections = await getUserCollections(n);
|
const collections = await getUserCollections(n);
|
||||||
return {
|
return {
|
||||||
id: n,
|
id: n,
|
||||||
collections
|
collections,
|
||||||
}
|
};
|
||||||
}))
|
}),
|
||||||
|
);
|
||||||
return users;
|
return users;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,10 +27,12 @@
|
|||||||
function constructPath() {
|
function constructPath() {
|
||||||
max = max !== undefined ? max : Math.max(...points);
|
max = max !== undefined ? max : Math.max(...points);
|
||||||
min = min !== undefined ? min : Math.min(...points);
|
min = min !== undefined ? min : Math.min(...points);
|
||||||
|
const mi = min as number;
|
||||||
|
const ma = max as number;
|
||||||
return points
|
return points
|
||||||
.map((point, i) => {
|
.map((point, i) => {
|
||||||
const x = (i / (points.length - 1)) * 100;
|
const x = (i / (points.length - 1)) * 100;
|
||||||
const y = 100 - ((point - min) / (max - min)) * 100;
|
const y = 100 - ((point - mi) / (ma - mi)) * 100;
|
||||||
return `${x},${y}`;
|
return `${x},${y}`;
|
||||||
})
|
})
|
||||||
.join(" ");
|
.join(" ");
|
||||||
|
|||||||
@@ -42,11 +42,9 @@
|
|||||||
export const invalidate = function () {
|
export const invalidate = function () {
|
||||||
if (scene) {
|
if (scene) {
|
||||||
geometries = scene.children
|
geometries = scene.children
|
||||||
.filter(
|
.filter((child) => "geometry" in child && child.isObject3D)
|
||||||
(child) => "geometry" in child && child.isObject3D && child.geometry,
|
|
||||||
)
|
|
||||||
.map((child) => {
|
.map((child) => {
|
||||||
return child.geometry;
|
return (child as Mesh).geometry;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,27 @@
|
|||||||
import { fastHashArrayBuffer } from "@nodes/utils";
|
import { fastHashArrayBuffer } from "@nodes/utils";
|
||||||
import { BufferAttribute, BufferGeometry, Float32BufferAttribute, Group, InstancedMesh, Material, Matrix4, Mesh } from "three";
|
import {
|
||||||
|
BufferAttribute,
|
||||||
|
BufferGeometry,
|
||||||
|
Float32BufferAttribute,
|
||||||
|
Group,
|
||||||
|
InstancedMesh,
|
||||||
|
Material,
|
||||||
|
Matrix4,
|
||||||
|
Mesh,
|
||||||
|
} from "three";
|
||||||
|
|
||||||
function fastArrayHash(arr: ArrayBuffer) {
|
function fastArrayHash(arr: Int32Array) {
|
||||||
let ints = new Uint8Array(arr);
|
const sampleDistance = Math.max(Math.floor(arr.length / 100), 1);
|
||||||
|
const sampleCount = Math.floor(arr.length / sampleDistance);
|
||||||
|
|
||||||
const sampleDistance = Math.max(Math.floor(ints.length / 100), 1);
|
let hash = new Int32Array(sampleCount);
|
||||||
const sampleCount = Math.floor(ints.length / sampleDistance);
|
|
||||||
|
|
||||||
let hash = new Uint8Array(sampleCount);
|
|
||||||
|
|
||||||
for (let i = 0; i < sampleCount; i++) {
|
for (let i = 0; i < sampleCount; i++) {
|
||||||
const index = i * sampleDistance;
|
const index = i * sampleDistance;
|
||||||
hash[i] = ints[index];
|
hash[i] = arr[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
return fastHashArrayBuffer(hash.buffer);
|
return fastHashArrayBuffer(hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createGeometryPool(parentScene: Group, material: Material) {
|
export function createGeometryPool(parentScene: Group, material: Material) {
|
||||||
@@ -26,8 +33,10 @@ export function createGeometryPool(parentScene: Group, material: Material) {
|
|||||||
let totalVertices = 0;
|
let totalVertices = 0;
|
||||||
let totalFaces = 0;
|
let totalFaces = 0;
|
||||||
|
|
||||||
function updateSingleGeometry(data: Int32Array, existingMesh: Mesh | null = null) {
|
function updateSingleGeometry(
|
||||||
|
data: Int32Array,
|
||||||
|
existingMesh: Mesh | null = null,
|
||||||
|
) {
|
||||||
let hash = fastArrayHash(data);
|
let hash = fastArrayHash(data);
|
||||||
|
|
||||||
let geometry = existingMesh ? existingMesh.geometry : new BufferGeometry();
|
let geometry = existingMesh ? existingMesh.geometry : new BufferGeometry();
|
||||||
@@ -50,11 +59,7 @@ export function createGeometryPool(parentScene: Group, material: Material) {
|
|||||||
index = indicesEnd;
|
index = indicesEnd;
|
||||||
|
|
||||||
// Vertices
|
// Vertices
|
||||||
const vertices = new Float32Array(
|
const vertices = new Float32Array(data.buffer, index * 4, vertexCount * 3);
|
||||||
data.buffer,
|
|
||||||
index * 4,
|
|
||||||
vertexCount * 3,
|
|
||||||
);
|
|
||||||
index = index + vertexCount * 3;
|
index = index + vertexCount * 3;
|
||||||
|
|
||||||
let posAttribute = geometry.getAttribute(
|
let posAttribute = geometry.getAttribute(
|
||||||
@@ -71,11 +76,7 @@ export function createGeometryPool(parentScene: Group, material: Material) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const normals = new Float32Array(
|
const normals = new Float32Array(data.buffer, index * 4, vertexCount * 3);
|
||||||
data.buffer,
|
|
||||||
index * 4,
|
|
||||||
vertexCount * 3,
|
|
||||||
);
|
|
||||||
index = index + vertexCount * 3;
|
index = index + vertexCount * 3;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@@ -109,11 +110,8 @@ export function createGeometryPool(parentScene: Group, material: Material) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
update(
|
update(newData: Int32Array[]) {
|
||||||
newData: Int32Array[],
|
|
||||||
) {
|
|
||||||
totalVertices = 0;
|
totalVertices = 0;
|
||||||
totalFaces = 0;
|
totalFaces = 0;
|
||||||
for (let i = 0; i < Math.max(newData.length, meshes.length); i++) {
|
for (let i = 0; i < Math.max(newData.length, meshes.length); i++) {
|
||||||
@@ -127,11 +125,14 @@ export function createGeometryPool(parentScene: Group, material: Material) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return { totalVertices, totalFaces };
|
return { totalVertices, totalFaces };
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createInstancedGeometryPool(parentScene: Group, material: Material) {
|
export function createInstancedGeometryPool(
|
||||||
|
parentScene: Group,
|
||||||
|
material: Material,
|
||||||
|
) {
|
||||||
const scene = new Group();
|
const scene = new Group();
|
||||||
parentScene.add(scene);
|
parentScene.add(scene);
|
||||||
|
|
||||||
@@ -139,19 +140,25 @@ export function createInstancedGeometryPool(parentScene: Group, material: Materi
|
|||||||
let totalVertices = 0;
|
let totalVertices = 0;
|
||||||
let totalFaces = 0;
|
let totalFaces = 0;
|
||||||
|
|
||||||
function updateSingleInstance(data: Int32Array, existingInstance: InstancedMesh | null = null) {
|
function updateSingleInstance(
|
||||||
|
data: Int32Array,
|
||||||
|
existingInstance: InstancedMesh | null = null,
|
||||||
|
) {
|
||||||
let hash = fastArrayHash(data);
|
let hash = fastArrayHash(data);
|
||||||
|
|
||||||
let geometry = existingInstance ? existingInstance.geometry : new BufferGeometry();
|
let geometry = existingInstance
|
||||||
|
? existingInstance.geometry
|
||||||
|
: new BufferGeometry();
|
||||||
|
|
||||||
// Extract data from the encoded array
|
// Extract data from the encoded array
|
||||||
let index = 0;
|
let index = 0;
|
||||||
const geometryType = data[index++];
|
// const geometryType = data[index++];
|
||||||
|
index++;
|
||||||
const vertexCount = data[index++];
|
const vertexCount = data[index++];
|
||||||
const faceCount = data[index++];
|
const faceCount = data[index++];
|
||||||
const instanceCount = data[index++];
|
const instanceCount = data[index++];
|
||||||
const stemDepth = data[index++];
|
// const stemDepth = data[index++];
|
||||||
|
index++;
|
||||||
totalVertices += vertexCount * instanceCount;
|
totalVertices += vertexCount * instanceCount;
|
||||||
totalFaces += faceCount * instanceCount;
|
totalFaces += faceCount * instanceCount;
|
||||||
|
|
||||||
@@ -168,11 +175,7 @@ export function createInstancedGeometryPool(parentScene: Group, material: Materi
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Vertices
|
// Vertices
|
||||||
const vertices = new Float32Array(
|
const vertices = new Float32Array(data.buffer, index * 4, vertexCount * 3);
|
||||||
data.buffer,
|
|
||||||
index * 4,
|
|
||||||
vertexCount * 3,
|
|
||||||
);
|
|
||||||
index = index + vertexCount * 3;
|
index = index + vertexCount * 3;
|
||||||
let posAttribute = geometry.getAttribute(
|
let posAttribute = geometry.getAttribute(
|
||||||
"position",
|
"position",
|
||||||
@@ -187,11 +190,7 @@ export function createInstancedGeometryPool(parentScene: Group, material: Materi
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const normals = new Float32Array(
|
const normals = new Float32Array(data.buffer, index * 4, vertexCount * 3);
|
||||||
data.buffer,
|
|
||||||
index * 4,
|
|
||||||
vertexCount * 3,
|
|
||||||
);
|
|
||||||
index = index + vertexCount * 3;
|
index = index + vertexCount * 3;
|
||||||
const normalsAttribute = geometry.getAttribute(
|
const normalsAttribute = geometry.getAttribute(
|
||||||
"normal",
|
"normal",
|
||||||
@@ -203,20 +202,23 @@ export function createInstancedGeometryPool(parentScene: Group, material: Materi
|
|||||||
geometry.setAttribute("normal", new Float32BufferAttribute(normals, 3));
|
geometry.setAttribute("normal", new Float32BufferAttribute(normals, 3));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (existingInstance && instanceCount > existingInstance.geometry.userData.count) {
|
if (
|
||||||
console.log("recreating instance")
|
existingInstance &&
|
||||||
|
instanceCount > existingInstance.geometry.userData.count
|
||||||
|
) {
|
||||||
|
console.log("recreating instance");
|
||||||
scene.remove(existingInstance);
|
scene.remove(existingInstance);
|
||||||
instances.splice(instances.indexOf(existingInstance), 1);
|
instances.splice(instances.indexOf(existingInstance), 1);
|
||||||
existingInstance = new InstancedMesh(geometry, material, instanceCount);
|
existingInstance = new InstancedMesh(geometry, material, instanceCount);
|
||||||
scene.add(existingInstance)
|
scene.add(existingInstance);
|
||||||
instances.push(existingInstance)
|
instances.push(existingInstance);
|
||||||
} else if (!existingInstance) {
|
} else if (!existingInstance) {
|
||||||
console.log("creating instance")
|
console.log("creating instance");
|
||||||
existingInstance = new InstancedMesh(geometry, material, instanceCount);
|
existingInstance = new InstancedMesh(geometry, material, instanceCount);
|
||||||
scene.add(existingInstance)
|
scene.add(existingInstance);
|
||||||
instances.push(existingInstance)
|
instances.push(existingInstance);
|
||||||
} else {
|
} else {
|
||||||
console.log("updating instance")
|
console.log("updating instance");
|
||||||
existingInstance.count = instanceCount;
|
existingInstance.count = instanceCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,28 +227,31 @@ export function createInstancedGeometryPool(parentScene: Group, material: Materi
|
|||||||
const matrices = new Float32Array(
|
const matrices = new Float32Array(
|
||||||
data.buffer,
|
data.buffer,
|
||||||
index * 4,
|
index * 4,
|
||||||
instanceCount * 16);
|
instanceCount * 16,
|
||||||
|
);
|
||||||
|
|
||||||
for (let i = 0; i < instanceCount; i++) {
|
for (let i = 0; i < instanceCount; i++) {
|
||||||
const matrix = new Matrix4().fromArray(matrices.subarray(i * 16, i * 16 + 16));
|
const matrix = new Matrix4().fromArray(
|
||||||
|
matrices.subarray(i * 16, i * 16 + 16),
|
||||||
|
);
|
||||||
existingInstance.setMatrixAt(i, matrix);
|
existingInstance.setMatrixAt(i, matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
geometry.userData = {
|
geometry.userData = {
|
||||||
vertexCount,
|
vertexCount,
|
||||||
faceCount,
|
faceCount,
|
||||||
count: Math.max(instanceCount, existingInstance.geometry.userData.count || 0),
|
count: Math.max(
|
||||||
|
instanceCount,
|
||||||
|
existingInstance.geometry.userData.count || 0,
|
||||||
|
),
|
||||||
hash,
|
hash,
|
||||||
};
|
};
|
||||||
|
|
||||||
existingInstance.instanceMatrix.needsUpdate = true;
|
existingInstance.instanceMatrix.needsUpdate = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
update(
|
update(newData: Int32Array[]) {
|
||||||
newData: Int32Array[],
|
|
||||||
) {
|
|
||||||
totalVertices = 0;
|
totalVertices = 0;
|
||||||
totalFaces = 0;
|
totalFaces = 0;
|
||||||
for (let i = 0; i < Math.max(newData.length, instances.length); i++) {
|
for (let i = 0; i < Math.max(newData.length, instances.length); i++) {
|
||||||
@@ -260,6 +265,6 @@ export function createInstancedGeometryPool(parentScene: Group, material: Materi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return { totalVertices, totalFaces };
|
return { totalVertices, totalFaces };
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,26 @@
|
|||||||
import type { Graph, NodeDefinition, NodeInput, NodeRegistry, RuntimeExecutor, SyncCache } from "@nodes/types";
|
import type {
|
||||||
import { concatEncodedArrays, createLogger, encodeFloat, fastHashArrayBuffer, type PerformanceStore } from "@nodes/utils";
|
Graph,
|
||||||
|
Node,
|
||||||
|
NodeDefinition,
|
||||||
|
NodeInput,
|
||||||
|
NodeRegistry,
|
||||||
|
RuntimeExecutor,
|
||||||
|
SyncCache,
|
||||||
|
} from "@nodes/types";
|
||||||
|
import {
|
||||||
|
concatEncodedArrays,
|
||||||
|
createLogger,
|
||||||
|
encodeFloat,
|
||||||
|
fastHashArrayBuffer,
|
||||||
|
type PerformanceStore,
|
||||||
|
} from "@nodes/utils";
|
||||||
|
|
||||||
const log = createLogger("runtime-executor");
|
const log = createLogger("runtime-executor");
|
||||||
log.mute()
|
log.mute();
|
||||||
|
|
||||||
function getValue(input: NodeInput, value?: unknown) {
|
function getValue(input: NodeInput, value?: unknown) {
|
||||||
if (value === undefined && "value" in input) {
|
if (value === undefined && "value" in input) {
|
||||||
value = input.value
|
value = input.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input.type === "float") {
|
if (input.type === "float") {
|
||||||
@@ -15,7 +29,13 @@ function getValue(input: NodeInput, value?: unknown) {
|
|||||||
|
|
||||||
if (Array.isArray(value)) {
|
if (Array.isArray(value)) {
|
||||||
if (input.type === "vec3") {
|
if (input.type === "vec3") {
|
||||||
return [0, value.length + 1, ...value.map(v => encodeFloat(v)), 1, 1] as number[];
|
return [
|
||||||
|
0,
|
||||||
|
value.length + 1,
|
||||||
|
...value.map((v) => encodeFloat(v)),
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
] as number[];
|
||||||
}
|
}
|
||||||
return [0, value.length + 1, ...value, 1, 1] as number[];
|
return [0, value.length + 1, ...value, 1, 1] as number[];
|
||||||
}
|
}
|
||||||
@@ -36,22 +56,23 @@ function getValue(input: NodeInput, value?: unknown) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class MemoryRuntimeExecutor implements RuntimeExecutor {
|
export class MemoryRuntimeExecutor implements RuntimeExecutor {
|
||||||
|
|
||||||
private definitionMap: Map<string, NodeDefinition> = new Map();
|
private definitionMap: Map<string, NodeDefinition> = new Map();
|
||||||
|
|
||||||
private randomSeed = Math.floor(Math.random() * 100000000);
|
private randomSeed = Math.floor(Math.random() * 100000000);
|
||||||
|
|
||||||
perf?: PerformanceStore;
|
perf?: PerformanceStore;
|
||||||
|
|
||||||
constructor(private registry: NodeRegistry, private cache?: SyncCache<Int32Array>) { }
|
constructor(
|
||||||
|
private registry: NodeRegistry,
|
||||||
|
private cache?: SyncCache<Int32Array>,
|
||||||
|
) {}
|
||||||
|
|
||||||
private async getNodeDefinitions(graph: Graph) {
|
private async getNodeDefinitions(graph: Graph) {
|
||||||
|
|
||||||
if (this.registry.status !== "ready") {
|
if (this.registry.status !== "ready") {
|
||||||
throw new Error("Node registry is not ready");
|
throw new Error("Node registry is not ready");
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.registry.load(graph.nodes.map(node => node.type));
|
await this.registry.load(graph.nodes.map((node) => node.type));
|
||||||
|
|
||||||
const typeMap = new Map<string, NodeDefinition>();
|
const typeMap = new Map<string, NodeDefinition>();
|
||||||
for (const node of graph.nodes) {
|
for (const node of graph.nodes) {
|
||||||
@@ -66,18 +87,22 @@ export class MemoryRuntimeExecutor implements RuntimeExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async addMetaData(graph: Graph) {
|
private async addMetaData(graph: Graph) {
|
||||||
|
|
||||||
// First, lets check if all nodes have a definition
|
// First, lets check if all nodes have a definition
|
||||||
this.definitionMap = await this.getNodeDefinitions(graph);
|
this.definitionMap = await this.getNodeDefinitions(graph);
|
||||||
|
|
||||||
const outputNode = graph.nodes.find(node => node.type.endsWith("/output"));
|
const outputNode = graph.nodes.find((node) =>
|
||||||
|
node.type.endsWith("/output"),
|
||||||
|
) as Node;
|
||||||
if (!outputNode) {
|
if (!outputNode) {
|
||||||
throw new Error("No output node found");
|
throw new Error("No output node found");
|
||||||
}
|
}
|
||||||
|
|
||||||
outputNode.tmp = outputNode.tmp || {};
|
outputNode.tmp = outputNode.tmp || {};
|
||||||
outputNode.tmp.depth = 0;
|
outputNode.tmp.depth = 0;
|
||||||
|
|
||||||
const nodeMap = new Map(graph.nodes.map(node => [node.id, node]));
|
const nodeMap = new Map<number, Node>(
|
||||||
|
graph.nodes.map((node) => [node.id, node]),
|
||||||
|
);
|
||||||
|
|
||||||
// loop through all edges and assign the parent and child nodes to each node
|
// loop through all edges and assign the parent and child nodes to each node
|
||||||
for (const edge of graph.edges) {
|
for (const edge of graph.edges) {
|
||||||
@@ -96,7 +121,7 @@ export class MemoryRuntimeExecutor implements RuntimeExecutor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const nodes = []
|
const nodes = [];
|
||||||
|
|
||||||
// loop through all the nodes and assign each nodes its depth
|
// loop through all the nodes and assign each nodes its depth
|
||||||
const stack = [outputNode];
|
const stack = [outputNode];
|
||||||
@@ -125,7 +150,6 @@ export class MemoryRuntimeExecutor implements RuntimeExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async execute(graph: Graph, settings: Record<string, unknown>) {
|
async execute(graph: Graph, settings: Record<string, unknown>) {
|
||||||
|
|
||||||
this.perf?.addPoint("runtime");
|
this.perf?.addPoint("runtime");
|
||||||
|
|
||||||
let a = performance.now();
|
let a = performance.now();
|
||||||
@@ -148,30 +172,31 @@ export class MemoryRuntimeExecutor implements RuntimeExecutor {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// we execute the nodes from the bottom up
|
// we execute the nodes from the bottom up
|
||||||
const sortedNodes = nodes.sort((a, b) => (b.tmp?.depth || 0) - (a.tmp?.depth || 0));
|
const sortedNodes = nodes.sort(
|
||||||
|
(a, b) => (b.tmp?.depth || 0) - (a.tmp?.depth || 0),
|
||||||
|
);
|
||||||
|
|
||||||
// here we store the intermediate results of the nodes
|
// here we store the intermediate results of the nodes
|
||||||
const results: Record<string, Int32Array> = {};
|
const results: Record<string, Int32Array> = {};
|
||||||
|
|
||||||
for (const node of sortedNodes) {
|
for (const node of sortedNodes) {
|
||||||
|
|
||||||
const node_type = this.definitionMap.get(node.type)!;
|
const node_type = this.definitionMap.get(node.type)!;
|
||||||
|
|
||||||
if (!node_type || !node.tmp || !node_type.execute) {
|
if (!node_type || !node.tmp || !node_type.execute) {
|
||||||
log.warn(`Node ${node.id} has no definition`);
|
log.warn(`Node ${node.id} has no definition`);
|
||||||
continue;
|
continue;
|
||||||
};
|
}
|
||||||
|
|
||||||
a = performance.now();
|
a = performance.now();
|
||||||
|
|
||||||
// Collect the inputs for the node
|
// Collect the inputs for the node
|
||||||
const inputs = Object.entries(node_type.inputs || {}).map(([key, input]) => {
|
const inputs = Object.entries(node_type.inputs || {}).map(
|
||||||
|
([key, input]) => {
|
||||||
if (input.type === "seed") {
|
if (input.type === "seed") {
|
||||||
if (settings["randomSeed"] === true) {
|
if (settings["randomSeed"] === true) {
|
||||||
return Math.floor(Math.random() * 100000000)
|
return Math.floor(Math.random() * 100000000);
|
||||||
} else {
|
} else {
|
||||||
return this.randomSeed
|
return this.randomSeed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,7 +209,9 @@ export class MemoryRuntimeExecutor implements RuntimeExecutor {
|
|||||||
const inputNode = node.tmp?.inputNodes?.[key];
|
const inputNode = node.tmp?.inputNodes?.[key];
|
||||||
if (inputNode) {
|
if (inputNode) {
|
||||||
if (results[inputNode.id] === undefined) {
|
if (results[inputNode.id] === undefined) {
|
||||||
throw new Error(`Node ${node.type} is missing input from node ${inputNode.type}`);
|
throw new Error(
|
||||||
|
`Node ${node.type} is missing input from node ${inputNode.type}`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return results[inputNode.id];
|
return results[inputNode.id];
|
||||||
}
|
}
|
||||||
@@ -195,13 +222,13 @@ export class MemoryRuntimeExecutor implements RuntimeExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return getValue(input);
|
return getValue(input);
|
||||||
});
|
},
|
||||||
|
);
|
||||||
b = performance.now();
|
b = performance.now();
|
||||||
|
|
||||||
this.perf?.addPoint("collected-inputs", b - a);
|
this.perf?.addPoint("collected-inputs", b - a);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
a = performance.now();
|
a = performance.now();
|
||||||
const encoded_inputs = concatEncodedArrays(inputs);
|
const encoded_inputs = concatEncodedArrays(inputs);
|
||||||
b = performance.now();
|
b = performance.now();
|
||||||
@@ -234,13 +261,10 @@ export class MemoryRuntimeExecutor implements RuntimeExecutor {
|
|||||||
this.perf?.addPoint("node/" + node_type.id, b - a);
|
this.perf?.addPoint("node/" + node_type.id, b - a);
|
||||||
log.log("Result:", results[node.id]);
|
log.log("Result:", results[node.id]);
|
||||||
log.groupEnd();
|
log.groupEnd();
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log.groupEnd();
|
log.groupEnd();
|
||||||
log.error(`Error executing node ${node_type.id || node.id}`, e);
|
log.error(`Error executing node ${node_type.id || node.id}`, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// return the result of the parent of the output node
|
// return the result of the parent of the output node
|
||||||
@@ -253,11 +277,9 @@ export class MemoryRuntimeExecutor implements RuntimeExecutor {
|
|||||||
this.perf?.endPoint("runtime");
|
this.perf?.endPoint("runtime");
|
||||||
|
|
||||||
return res as unknown as Int32Array;
|
return res as unknown as Int32Array;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getPerformanceData() {
|
getPerformanceData() {
|
||||||
return this.perf?.get();
|
return this.perf?.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,14 +6,16 @@ import { MemoryRuntimeCache } from "./runtime-executor-cache";
|
|||||||
|
|
||||||
const cache = new MemoryRuntimeCache();
|
const cache = new MemoryRuntimeCache();
|
||||||
const indexDbCache = new IndexDBCache("node-registry");
|
const indexDbCache = new IndexDBCache("node-registry");
|
||||||
const nodeRegistry = new RemoteNodeRegistry("");
|
const nodeRegistry = new RemoteNodeRegistry("", indexDbCache);
|
||||||
nodeRegistry.cache = indexDbCache;
|
|
||||||
const executor = new MemoryRuntimeExecutor(nodeRegistry, cache);
|
const executor = new MemoryRuntimeExecutor(nodeRegistry, cache);
|
||||||
|
|
||||||
const performanceStore = createPerformanceStore();
|
const performanceStore = createPerformanceStore();
|
||||||
executor.perf = performanceStore;
|
executor.perf = performanceStore;
|
||||||
|
|
||||||
export async function executeGraph(graph: Graph, settings: Record<string, unknown>): Promise<Int32Array> {
|
export async function executeGraph(
|
||||||
|
graph: Graph,
|
||||||
|
settings: Record<string, unknown>,
|
||||||
|
): Promise<Int32Array> {
|
||||||
await nodeRegistry.load(graph.nodes.map((n) => n.type));
|
await nodeRegistry.load(graph.nodes.map((n) => n.type));
|
||||||
performanceStore.startRun();
|
performanceStore.startRun();
|
||||||
let res = await executor.execute(graph, settings);
|
let res = await executor.execute(graph, settings);
|
||||||
|
|||||||
@@ -1,7 +1,3 @@
|
|||||||
<script module lang="ts">
|
|
||||||
let openSections = localState<Record<string, boolean>>("open-details", {});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import NestedSettings from "./NestedSettings.svelte";
|
import NestedSettings from "./NestedSettings.svelte";
|
||||||
import { localState } from "$lib/helpers/localState.svelte";
|
import { localState } from "$lib/helpers/localState.svelte";
|
||||||
@@ -12,10 +8,15 @@
|
|||||||
|
|
||||||
type InputType = NodeInput | Button;
|
type InputType = NodeInput | Button;
|
||||||
|
|
||||||
interface Nested {
|
type SettingsNode = InputType | SettingsGroup;
|
||||||
[key: string]: (Nested & { title?: string }) | InputType;
|
|
||||||
|
interface SettingsGroup {
|
||||||
|
title?: string;
|
||||||
|
[key: string]: any;
|
||||||
}
|
}
|
||||||
type SettingsType = Record<string, Nested>;
|
|
||||||
|
type SettingsType = Record<string, SettingsNode>;
|
||||||
|
|
||||||
type SettingsValue = Record<
|
type SettingsValue = Record<
|
||||||
string,
|
string,
|
||||||
Record<string, unknown> | string | number | boolean | number[]
|
Record<string, unknown> | string | number | boolean | number[]
|
||||||
@@ -29,38 +30,57 @@
|
|||||||
depth?: number;
|
depth?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Local persistent state for <details> sections
|
||||||
|
const openSections = localState<Record<string, boolean>>("open-details", {});
|
||||||
|
|
||||||
let { id, key = "", value = $bindable(), type, depth = 0 }: Props = $props();
|
let { id, key = "", value = $bindable(), type, depth = 0 }: Props = $props();
|
||||||
|
|
||||||
function isNodeInput(v: InputType | Nested): v is InputType {
|
function isNodeInput(v: SettingsNode | undefined): v is InputType {
|
||||||
return v && "type" in v;
|
return !!v && typeof v === "object" && "type" in v;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDefaultValue() {
|
function getDefaultValue(): unknown {
|
||||||
if (key === "") return;
|
if (key === "" || key === "title") return;
|
||||||
if (key === "title") return;
|
|
||||||
if (Array.isArray(type[key]?.options)) {
|
const node = type[key];
|
||||||
|
|
||||||
|
if (!isNodeInput(node)) return;
|
||||||
|
|
||||||
|
const anyNode = node as any;
|
||||||
|
|
||||||
|
// select input: use index into options
|
||||||
|
if (Array.isArray(anyNode.options)) {
|
||||||
if (value?.[key] !== undefined) {
|
if (value?.[key] !== undefined) {
|
||||||
return type[key]?.options?.indexOf(value?.[key]);
|
return anyNode.options.indexOf(value[key]);
|
||||||
} else {
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (value?.[key] !== undefined) return value?.[key];
|
|
||||||
if (type[key]?.value !== undefined) return type[key]?.value;
|
|
||||||
|
|
||||||
if (isNodeInput(type[key])) {
|
if (value?.[key] !== undefined) return value[key];
|
||||||
if (type[key].type === "boolean") return 0;
|
|
||||||
if (type[key].type === "float") return 0.5;
|
if ("value" in node && anyNode.value !== undefined) {
|
||||||
if (type[key].type === "integer") return 0;
|
return anyNode.value;
|
||||||
if (type[key].type === "select") return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (node.type) {
|
||||||
|
case "boolean":
|
||||||
return 0;
|
return 0;
|
||||||
|
case "float":
|
||||||
|
return 0.5;
|
||||||
|
case "integer":
|
||||||
|
case "select":
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let internalValue = $state(getDefaultValue());
|
let internalValue = $state(getDefaultValue());
|
||||||
|
|
||||||
let open = $state(openSections[id]);
|
let open = $state(openSections[id]);
|
||||||
if (depth > 0 && !isNodeInput(type[key])) {
|
|
||||||
|
// Persist <details> open/closed state for groups
|
||||||
|
if (depth > 0 && !isNodeInput(type[key!])) {
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
if (open !== undefined) {
|
if (open !== undefined) {
|
||||||
openSections[id] = open;
|
openSections[id] = open;
|
||||||
@@ -68,21 +88,26 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sync internalValue back into `value`
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
if (key === "" || internalValue === undefined) return;
|
if (key === "" || internalValue === undefined) return;
|
||||||
|
|
||||||
|
const node = type[key];
|
||||||
|
|
||||||
if (
|
if (
|
||||||
isNodeInput(type[key]) &&
|
isNodeInput(node) &&
|
||||||
Array.isArray(type[key]?.options) &&
|
Array.isArray((node as any).options) &&
|
||||||
typeof internalValue === "number"
|
typeof internalValue === "number"
|
||||||
) {
|
) {
|
||||||
value[key] = type[key].options?.[internalValue];
|
value[key] = (node as any).options[internalValue] as any;
|
||||||
} else {
|
} else {
|
||||||
value[key] = internalValue;
|
value[key] = internalValue as any;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if key && isNodeInput(type?.[key])}
|
{#if key && isNodeInput(type?.[key])}
|
||||||
|
<!-- Leaf input -->
|
||||||
<div class="input input-{type[key].type}" class:first-level={depth === 1}>
|
<div class="input input-{type[key].type}" class:first-level={depth === 1}>
|
||||||
{#if type[key].type === "button"}
|
{#if type[key].type === "button"}
|
||||||
<button onclick={() => console.log(type[key])}>
|
<button onclick={() => console.log(type[key])}>
|
||||||
@@ -94,7 +119,8 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{:else if depth === 0}
|
{:else if depth === 0}
|
||||||
{#each Object.keys(type ?? {}).filter((key) => key !== "title") as childKey}
|
<!-- Root: iterate over top-level keys -->
|
||||||
|
{#each Object.keys(type ?? {}).filter((k) => k !== "title") as childKey}
|
||||||
<NestedSettings
|
<NestedSettings
|
||||||
id={`${id}.${childKey}`}
|
id={`${id}.${childKey}`}
|
||||||
key={childKey}
|
key={childKey}
|
||||||
@@ -105,18 +131,19 @@
|
|||||||
{/each}
|
{/each}
|
||||||
<hr />
|
<hr />
|
||||||
{:else if key && type?.[key]}
|
{:else if key && type?.[key]}
|
||||||
|
<!-- Group -->
|
||||||
{#if depth > 0}
|
{#if depth > 0}
|
||||||
<hr />
|
<hr />
|
||||||
{/if}
|
{/if}
|
||||||
<details bind:open>
|
<details bind:open>
|
||||||
<summary><p>{type[key]?.title || key}</p></summary>
|
<summary><p>{(type[key] as SettingsGroup).title || key}</p></summary>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
{#each Object.keys(type[key]).filter((key) => key !== "title") as childKey}
|
{#each Object.keys(type[key] as SettingsGroup).filter((k) => k !== "title") as childKey}
|
||||||
<NestedSettings
|
<NestedSettings
|
||||||
id={`${id}.${childKey}`}
|
id={`${id}.${childKey}`}
|
||||||
key={childKey}
|
key={childKey}
|
||||||
value={value[key] as SettingsValue}
|
value={value[key] as SettingsValue}
|
||||||
type={type[key] as SettingsType}
|
type={type[key] as unknown as SettingsType}
|
||||||
depth={depth + 1}
|
depth={depth + 1}
|
||||||
/>
|
/>
|
||||||
{/each}
|
{/each}
|
||||||
@@ -156,6 +183,7 @@
|
|||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.input-boolean > label {
|
.input-boolean > label {
|
||||||
order: 2;
|
order: 2;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { localState } from "$lib/helpers/localState.svelte";
|
import { localState } from "$lib/helpers/localState.svelte";
|
||||||
import type { NodeInput } from "@nodes/types";
|
import type { NodeInput } from "@nodes/types";
|
||||||
|
import type { SettingsType } from ".";
|
||||||
|
|
||||||
const themes = [
|
const themes = [
|
||||||
"dark",
|
"dark",
|
||||||
@@ -118,7 +119,7 @@ export const AppSettingTypes = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
} as const;
|
} as const satisfies SettingsType;
|
||||||
|
|
||||||
type IsInputDefinition<T> = T extends NodeInput ? T : never;
|
type IsInputDefinition<T> = T extends NodeInput ? T : never;
|
||||||
type HasTitle = { title: string };
|
type HasTitle = { title: string };
|
||||||
|
|||||||
@@ -2,12 +2,26 @@ import type { NodeInput } from "@nodes/types";
|
|||||||
|
|
||||||
type Button = { type: "button"; label?: string };
|
type Button = { type: "button"; label?: string };
|
||||||
|
|
||||||
|
export type SettingsStore = {
|
||||||
|
[key: string]: SettingsStore | string | number | boolean;
|
||||||
|
};
|
||||||
|
|
||||||
type InputType = NodeInput | Button;
|
type InputType = NodeInput | Button;
|
||||||
|
|
||||||
export interface SettingsType {
|
type SettingsNode = InputType | SettingsGroup;
|
||||||
[key: string]: (SettingsType & { title?: string }) | InputType;
|
|
||||||
|
export interface SettingsGroup {
|
||||||
|
title?: string;
|
||||||
|
[key: string]: SettingsNode | string | number | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type SettingsStore = {
|
export type SettingsType = Record<string, SettingsNode>;
|
||||||
[key: string]: SettingsStore | string | number | boolean
|
|
||||||
};
|
export type SettingsValue = Record<
|
||||||
|
string,
|
||||||
|
Record<string, unknown> | string | number | boolean | number[]
|
||||||
|
>;
|
||||||
|
|
||||||
|
export function isNodeInput(v: SettingsNode | undefined): v is InputType {
|
||||||
|
return !!v && "type" in v;
|
||||||
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
import { IndexDBCache, RemoteNodeRegistry } from "@nodes/registry";
|
import { IndexDBCache, RemoteNodeRegistry } from "@nodes/registry";
|
||||||
import { createPerformanceStore } from "@nodes/utils";
|
import { createPerformanceStore } from "@nodes/utils";
|
||||||
import BenchmarkPanel from "$lib/sidebar/panels/BenchmarkPanel.svelte";
|
import BenchmarkPanel from "$lib/sidebar/panels/BenchmarkPanel.svelte";
|
||||||
|
import { debounceAsyncFunction } from "$lib/helpers";
|
||||||
|
|
||||||
let performanceStore = createPerformanceStore();
|
let performanceStore = createPerformanceStore();
|
||||||
|
|
||||||
@@ -79,10 +80,8 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
let runIndex = 0;
|
let runIndex = 0;
|
||||||
const handleUpdate = async (
|
const handleUpdate = debounceAsyncFunction(
|
||||||
g: Graph,
|
async (g: Graph, s: Record<string, any> = graphSettings) => {
|
||||||
s: Record<string, any> = graphSettings,
|
|
||||||
) => {
|
|
||||||
runIndex++;
|
runIndex++;
|
||||||
performanceStore.startRun();
|
performanceStore.startRun();
|
||||||
try {
|
try {
|
||||||
@@ -112,7 +111,8 @@
|
|||||||
} finally {
|
} finally {
|
||||||
performanceStore.stopRun();
|
performanceStore.stopRun();
|
||||||
}
|
}
|
||||||
};
|
},
|
||||||
|
);
|
||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
|
|||||||
@@ -1,27 +1,36 @@
|
|||||||
import type { RequestHandler } from "./$types";
|
import type { EntryGenerator, RequestHandler } from "./$types";
|
||||||
import * as registry from "$lib/node-registry";
|
import * as registry from "$lib/node-registry";
|
||||||
import type { EntryGenerator } from "../$types";
|
|
||||||
|
|
||||||
export const prerender = true;
|
export const prerender = true;
|
||||||
|
|
||||||
export const entries: EntryGenerator = async () => {
|
export const entries: EntryGenerator = async () => {
|
||||||
const users = await registry.getUsers();
|
const users = await registry.getUsers();
|
||||||
return users.map(user => {
|
return users
|
||||||
return user.collections.map(collection => {
|
.map((user) => {
|
||||||
return collection.nodes.map(node => {
|
return user.collections.map((collection) => {
|
||||||
return { user: user.id, collection: collection.id.split("/")[1], node: node.id.split("/")[2] }
|
return collection.nodes.map((node) => {
|
||||||
|
return {
|
||||||
|
user: user.id,
|
||||||
|
collection: collection.id.split("/")[1],
|
||||||
|
node: node.id.split("/")[2],
|
||||||
|
};
|
||||||
|
});
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
}).flat(2);
|
.flat(2);
|
||||||
}
|
};
|
||||||
|
|
||||||
export const GET: RequestHandler = async function GET({ params }) {
|
export const GET: RequestHandler = async function GET({ params }) {
|
||||||
|
const wasm = await registry.getWasm(
|
||||||
const wasm = await registry.getWasm(`${params.user}/${params.collection}/${params.node}`);
|
`${params.user}/${params.collection}/${params.node}`,
|
||||||
|
);
|
||||||
|
|
||||||
if (!wasm) {
|
if (!wasm) {
|
||||||
return new Response("Not found", { status: 404 });
|
return new Response("Not found", { status: 404 });
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Response(wasm, { status: 200, headers: { "Content-Type": "application/wasm" } });
|
return new Response(wasm, {
|
||||||
}
|
status: 200,
|
||||||
|
headers: { "Content-Type": "application/wasm" },
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Graph, NodeDefinition, NodeType } from "./types";
|
import type { Graph, NodeDefinition, NodeType } from "./types";
|
||||||
|
|
||||||
export interface NodeRegistry {
|
export interface NodeRegistry {
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -6,11 +6,23 @@ const DefaultOptionsSchema = z.object({
|
|||||||
setting: z.string().optional(),
|
setting: z.string().optional(),
|
||||||
label: z.string().optional(),
|
label: z.string().optional(),
|
||||||
description: z.string().optional(),
|
description: z.string().optional(),
|
||||||
accepts: z.array(z.string()).optional(),
|
accepts: z
|
||||||
|
.array(
|
||||||
|
z.union([
|
||||||
|
z.literal("float"),
|
||||||
|
z.literal("integer"),
|
||||||
|
z.literal("boolean"),
|
||||||
|
z.literal("select"),
|
||||||
|
z.literal("seed"),
|
||||||
|
z.literal("vec3"),
|
||||||
|
z.literal("geometry"),
|
||||||
|
z.literal("path"),
|
||||||
|
]),
|
||||||
|
)
|
||||||
|
.optional(),
|
||||||
hidden: z.boolean().optional(),
|
hidden: z.boolean().optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
export const NodeInputFloatSchema = z.object({
|
export const NodeInputFloatSchema = z.object({
|
||||||
...DefaultOptionsSchema.shape,
|
...DefaultOptionsSchema.shape,
|
||||||
type: z.literal("float"),
|
type: z.literal("float"),
|
||||||
@@ -40,7 +52,7 @@ export const NodeInputSelectSchema = z.object({
|
|||||||
...DefaultOptionsSchema.shape,
|
...DefaultOptionsSchema.shape,
|
||||||
type: z.literal("select"),
|
type: z.literal("select"),
|
||||||
options: z.array(z.string()).optional(),
|
options: z.array(z.string()).optional(),
|
||||||
value: z.number().optional(),
|
value: z.string().optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const NodeInputSeedSchema = z.object({
|
export const NodeInputSeedSchema = z.object({
|
||||||
@@ -74,7 +86,7 @@ export const NodeInputSchema = z.union([
|
|||||||
NodeInputSeedSchema,
|
NodeInputSeedSchema,
|
||||||
NodeInputVec3Schema,
|
NodeInputVec3Schema,
|
||||||
NodeInputGeometrySchema,
|
NodeInputGeometrySchema,
|
||||||
NodeInputPathSchema
|
NodeInputPathSchema,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
export type NodeInput = z.infer<typeof NodeInputSchema>;
|
export type NodeInput = z.infer<typeof NodeInputSchema>;
|
||||||
|
|||||||
@@ -8,22 +8,6 @@ export const NodeTypeSchema = z
|
|||||||
|
|
||||||
export type NodeType = z.infer<typeof NodeTypeSchema>;
|
export type NodeType = z.infer<typeof NodeTypeSchema>;
|
||||||
|
|
||||||
export const NodeSchema = z.object({
|
|
||||||
id: z.number(),
|
|
||||||
type: NodeTypeSchema,
|
|
||||||
tmp: z.any().optional(),
|
|
||||||
props: z
|
|
||||||
.record(z.string(), z.union([z.number(), z.array(z.number())]))
|
|
||||||
.optional(),
|
|
||||||
meta: z
|
|
||||||
.object({
|
|
||||||
title: z.string().optional(),
|
|
||||||
lastModified: z.string().optional(),
|
|
||||||
})
|
|
||||||
.optional(),
|
|
||||||
position: z.tuple([z.number(), z.number()]),
|
|
||||||
});
|
|
||||||
|
|
||||||
export type Node = {
|
export type Node = {
|
||||||
tmp?: {
|
tmp?: {
|
||||||
depth?: number;
|
depth?: number;
|
||||||
@@ -55,6 +39,21 @@ export const NodeDefinitionSchema = z.object({
|
|||||||
.optional(),
|
.optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const NodeSchema = z.object({
|
||||||
|
id: z.number(),
|
||||||
|
type: NodeTypeSchema,
|
||||||
|
props: z
|
||||||
|
.record(z.string(), z.union([z.number(), z.array(z.number())]))
|
||||||
|
.optional(),
|
||||||
|
meta: z
|
||||||
|
.object({
|
||||||
|
title: z.string().optional(),
|
||||||
|
lastModified: z.string().optional(),
|
||||||
|
})
|
||||||
|
.optional(),
|
||||||
|
position: z.tuple([z.number(), z.number()]),
|
||||||
|
});
|
||||||
|
|
||||||
export type NodeDefinition = z.infer<typeof NodeDefinitionSchema> & {
|
export type NodeDefinition = z.infer<typeof NodeDefinitionSchema> & {
|
||||||
execute(input: Int32Array): Int32Array;
|
execute(input: Int32Array): Int32Array;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,12 +3,13 @@
|
|||||||
title?: string;
|
title?: string;
|
||||||
transparent?: boolean;
|
transparent?: boolean;
|
||||||
children?: import('svelte').Snippet;
|
children?: import('svelte').Snippet;
|
||||||
|
open?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
let { title = "Details", transparent = false, children }: Props = $props();
|
let { title = "Details", transparent = false, children, open = $bindable(false) }: Props = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<details class:transparent>
|
<details class:transparent bind:open>
|
||||||
<summary>{title}</summary>
|
<summary>{title}</summary>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
{@render children?.()}
|
{@render children?.()}
|
||||||
@@ -33,7 +34,4 @@
|
|||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
|
||||||
/* padding-left: 12px; */
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,47 +1,84 @@
|
|||||||
|
|
||||||
// https://github.com/6502/sha256/blob/main/sha256.js
|
// https://github.com/6502/sha256/blob/main/sha256.js
|
||||||
function sha256(data?: string | Uint8Array) {
|
function sha256(data?: string | Int32Array) {
|
||||||
let h0 = 0x6a09e667, h1 = 0xbb67ae85, h2 = 0x3c6ef372, h3 = 0xa54ff53a,
|
let h0 = 0x6a09e667,
|
||||||
h4 = 0x510e527f, h5 = 0x9b05688c, h6 = 0x1f83d9ab, h7 = 0x5be0cd19,
|
h1 = 0xbb67ae85,
|
||||||
tsz = 0, bp = 0;
|
h2 = 0x3c6ef372,
|
||||||
const k = [0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
h3 = 0xa54ff53a,
|
||||||
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
h4 = 0x510e527f,
|
||||||
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
h5 = 0x9b05688c,
|
||||||
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
h6 = 0x1f83d9ab,
|
||||||
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
h7 = 0x5be0cd19,
|
||||||
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
tsz = 0,
|
||||||
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
bp = 0;
|
||||||
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2],
|
const k = [
|
||||||
rrot = (x, n) => (x >>> n) | (x << (32 - n)),
|
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
|
||||||
|
0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
|
||||||
|
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
|
||||||
|
0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
||||||
|
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
|
||||||
|
0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
|
||||||
|
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
|
||||||
|
0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
||||||
|
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
|
||||||
|
0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
|
||||||
|
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
|
||||||
|
],
|
||||||
|
rrot = (x: number, n: number) => (x >>> n) | (x << (32 - n)),
|
||||||
w = new Uint32Array(64),
|
w = new Uint32Array(64),
|
||||||
buf = new Uint8Array(64),
|
buf = new Uint8Array(64),
|
||||||
process = () => {
|
process = () => {
|
||||||
for (let j = 0, r = 0; j < 16; j++, r += 4) {
|
for (let j = 0, r = 0; j < 16; j++, r += 4) {
|
||||||
w[j] = (buf[r] << 24) | (buf[r + 1] << 16) | (buf[r + 2] << 8) | buf[r + 3];
|
w[j] =
|
||||||
|
(buf[r] << 24) | (buf[r + 1] << 16) | (buf[r + 2] << 8) | buf[r + 3];
|
||||||
}
|
}
|
||||||
for (let j = 16; j < 64; j++) {
|
for (let j = 16; j < 64; j++) {
|
||||||
let s0 = rrot(w[j - 15], 7) ^ rrot(w[j - 15], 18) ^ (w[j - 15] >>> 3);
|
let s0 = rrot(w[j - 15], 7) ^ rrot(w[j - 15], 18) ^ (w[j - 15] >>> 3);
|
||||||
let s1 = rrot(w[j - 2], 17) ^ rrot(w[j - 2], 19) ^ (w[j - 2] >>> 10);
|
let s1 = rrot(w[j - 2], 17) ^ rrot(w[j - 2], 19) ^ (w[j - 2] >>> 10);
|
||||||
w[j] = (w[j - 16] + s0 + w[j - 7] + s1) | 0;
|
w[j] = (w[j - 16] + s0 + w[j - 7] + s1) | 0;
|
||||||
}
|
}
|
||||||
let a = h0, b = h1, c = h2, d = h3, e = h4, f = h5, g = h6, h = h7;
|
let a = h0,
|
||||||
|
b = h1,
|
||||||
|
c = h2,
|
||||||
|
d = h3,
|
||||||
|
e = h4,
|
||||||
|
f = h5,
|
||||||
|
g = h6,
|
||||||
|
h = h7;
|
||||||
for (let j = 0; j < 64; j++) {
|
for (let j = 0; j < 64; j++) {
|
||||||
let S1 = rrot(e, 6) ^ rrot(e, 11) ^ rrot(e, 25),
|
let S1 = rrot(e, 6) ^ rrot(e, 11) ^ rrot(e, 25),
|
||||||
ch = (e & f) ^ ((~e) & g),
|
ch = (e & f) ^ (~e & g),
|
||||||
t1 = (h + S1 + ch + k[j] + w[j]) | 0,
|
t1 = (h + S1 + ch + k[j] + w[j]) | 0,
|
||||||
S0 = rrot(a, 2) ^ rrot(a, 13) ^ rrot(a, 22),
|
S0 = rrot(a, 2) ^ rrot(a, 13) ^ rrot(a, 22),
|
||||||
maj = (a & b) ^ (a & c) ^ (b & c),
|
maj = (a & b) ^ (a & c) ^ (b & c),
|
||||||
t2 = (S0 + maj) | 0;
|
t2 = (S0 + maj) | 0;
|
||||||
h = g; g = f; f = e; e = (d + t1) | 0; d = c; c = b; b = a; a = (t1 + t2) | 0;
|
h = g;
|
||||||
|
g = f;
|
||||||
|
f = e;
|
||||||
|
e = (d + t1) | 0;
|
||||||
|
d = c;
|
||||||
|
c = b;
|
||||||
|
b = a;
|
||||||
|
a = (t1 + t2) | 0;
|
||||||
}
|
}
|
||||||
h0 = (h0 + a) | 0; h1 = (h1 + b) | 0; h2 = (h2 + c) | 0; h3 = (h3 + d) | 0;
|
h0 = (h0 + a) | 0;
|
||||||
h4 = (h4 + e) | 0; h5 = (h5 + f) | 0; h6 = (h6 + g) | 0; h7 = (h7 + h) | 0;
|
h1 = (h1 + b) | 0;
|
||||||
|
h2 = (h2 + c) | 0;
|
||||||
|
h3 = (h3 + d) | 0;
|
||||||
|
h4 = (h4 + e) | 0;
|
||||||
|
h5 = (h5 + f) | 0;
|
||||||
|
h6 = (h6 + g) | 0;
|
||||||
|
h7 = (h7 + h) | 0;
|
||||||
bp = 0;
|
bp = 0;
|
||||||
},
|
},
|
||||||
add = data => {
|
add = (input: string | Int32Array) => {
|
||||||
if (typeof data === "string") {
|
const data =
|
||||||
data = typeof TextEncoder === "undefined" ? Buffer.from(data) : (new TextEncoder).encode(data);
|
typeof input === "string"
|
||||||
}
|
? typeof TextEncoder === "undefined"
|
||||||
|
? //@ts-ignore
|
||||||
|
Buffer.from(input)
|
||||||
|
: new TextEncoder().encode(input)
|
||||||
|
: input;
|
||||||
|
|
||||||
for (let i = 0; i < data.length; i++) {
|
for (let i = 0; i < data.length; i++) {
|
||||||
buf[bp++] = data[i];
|
buf[bp++] = data[i];
|
||||||
if (bp === 64) process();
|
if (bp === 64) process();
|
||||||
@@ -49,7 +86,8 @@ function sha256(data?: string | Uint8Array) {
|
|||||||
tsz += data.length;
|
tsz += data.length;
|
||||||
},
|
},
|
||||||
digest = () => {
|
digest = () => {
|
||||||
buf[bp++] = 0x80; if (bp == 64) process();
|
buf[bp++] = 0x80;
|
||||||
|
if (bp == 64) process();
|
||||||
if (bp + 8 > 64) {
|
if (bp + 8 > 64) {
|
||||||
while (bp < 64) buf[bp++] = 0x00;
|
while (bp < 64) buf[bp++] = 0x00;
|
||||||
process();
|
process();
|
||||||
@@ -57,24 +95,48 @@ function sha256(data?: string | Uint8Array) {
|
|||||||
while (bp < 58) buf[bp++] = 0x00;
|
while (bp < 58) buf[bp++] = 0x00;
|
||||||
// Max number of bytes is 35,184,372,088,831
|
// Max number of bytes is 35,184,372,088,831
|
||||||
let L = tsz * 8;
|
let L = tsz * 8;
|
||||||
buf[bp++] = (L / 1099511627776.) & 255;
|
buf[bp++] = (L / 1099511627776) & 255;
|
||||||
buf[bp++] = (L / 4294967296.) & 255;
|
buf[bp++] = (L / 4294967296) & 255;
|
||||||
buf[bp++] = L >>> 24;
|
buf[bp++] = L >>> 24;
|
||||||
buf[bp++] = (L >>> 16) & 255;
|
buf[bp++] = (L >>> 16) & 255;
|
||||||
buf[bp++] = (L >>> 8) & 255;
|
buf[bp++] = (L >>> 8) & 255;
|
||||||
buf[bp++] = L & 255;
|
buf[bp++] = L & 255;
|
||||||
process();
|
process();
|
||||||
let reply = new Uint8Array(32);
|
let reply = new Uint8Array(32);
|
||||||
reply[0] = h0 >>> 24; reply[1] = (h0 >>> 16) & 255; reply[2] = (h0 >>> 8) & 255; reply[3] = h0 & 255;
|
reply[0] = h0 >>> 24;
|
||||||
reply[4] = h1 >>> 24; reply[5] = (h1 >>> 16) & 255; reply[6] = (h1 >>> 8) & 255; reply[7] = h1 & 255;
|
reply[1] = (h0 >>> 16) & 255;
|
||||||
reply[8] = h2 >>> 24; reply[9] = (h2 >>> 16) & 255; reply[10] = (h2 >>> 8) & 255; reply[11] = h2 & 255;
|
reply[2] = (h0 >>> 8) & 255;
|
||||||
reply[12] = h3 >>> 24; reply[13] = (h3 >>> 16) & 255; reply[14] = (h3 >>> 8) & 255; reply[15] = h3 & 255;
|
reply[3] = h0 & 255;
|
||||||
reply[16] = h4 >>> 24; reply[17] = (h4 >>> 16) & 255; reply[18] = (h4 >>> 8) & 255; reply[19] = h4 & 255;
|
reply[4] = h1 >>> 24;
|
||||||
reply[20] = h5 >>> 24; reply[21] = (h5 >>> 16) & 255; reply[22] = (h5 >>> 8) & 255; reply[23] = h5 & 255;
|
reply[5] = (h1 >>> 16) & 255;
|
||||||
reply[24] = h6 >>> 24; reply[25] = (h6 >>> 16) & 255; reply[26] = (h6 >>> 8) & 255; reply[27] = h6 & 255;
|
reply[6] = (h1 >>> 8) & 255;
|
||||||
reply[28] = h7 >>> 24; reply[29] = (h7 >>> 16) & 255; reply[30] = (h7 >>> 8) & 255; reply[31] = h7 & 255;
|
reply[7] = h1 & 255;
|
||||||
|
reply[8] = h2 >>> 24;
|
||||||
|
reply[9] = (h2 >>> 16) & 255;
|
||||||
|
reply[10] = (h2 >>> 8) & 255;
|
||||||
|
reply[11] = h2 & 255;
|
||||||
|
reply[12] = h3 >>> 24;
|
||||||
|
reply[13] = (h3 >>> 16) & 255;
|
||||||
|
reply[14] = (h3 >>> 8) & 255;
|
||||||
|
reply[15] = h3 & 255;
|
||||||
|
reply[16] = h4 >>> 24;
|
||||||
|
reply[17] = (h4 >>> 16) & 255;
|
||||||
|
reply[18] = (h4 >>> 8) & 255;
|
||||||
|
reply[19] = h4 & 255;
|
||||||
|
reply[20] = h5 >>> 24;
|
||||||
|
reply[21] = (h5 >>> 16) & 255;
|
||||||
|
reply[22] = (h5 >>> 8) & 255;
|
||||||
|
reply[23] = h5 & 255;
|
||||||
|
reply[24] = h6 >>> 24;
|
||||||
|
reply[25] = (h6 >>> 16) & 255;
|
||||||
|
reply[26] = (h6 >>> 8) & 255;
|
||||||
|
reply[27] = h6 & 255;
|
||||||
|
reply[28] = h7 >>> 24;
|
||||||
|
reply[29] = (h7 >>> 16) & 255;
|
||||||
|
reply[30] = (h7 >>> 8) & 255;
|
||||||
|
reply[31] = h7 & 255;
|
||||||
let res = "";
|
let res = "";
|
||||||
reply.forEach(x => res += ("0" + x.toString(16)).slice(-2));
|
reply.forEach((x) => (res += ("0" + x.toString(16)).slice(-2)));
|
||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -83,8 +145,8 @@ function sha256(data?: string | Uint8Array) {
|
|||||||
return { add, digest };
|
return { add, digest };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fastHashArrayBuffer(buffer: ArrayBuffer): string {
|
export function fastHashArrayBuffer(buffer: string | Int32Array): string {
|
||||||
return sha256(new Uint8Array(buffer)).digest();
|
return sha256(buffer).digest();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shamelessly copied from
|
// Shamelessly copied from
|
||||||
@@ -101,22 +163,19 @@ export function fastHashString(input: string) {
|
|||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export function fastHash(input: (string | Int32Array | number)[]) {
|
export function fastHash(input: (string | Int32Array | number)[]) {
|
||||||
|
|
||||||
const s = sha256();
|
const s = sha256();
|
||||||
|
|
||||||
for (let i = 0; i < input.length; i++) {
|
for (let i = 0; i < input.length; i++) {
|
||||||
const v = input[i]
|
const v = input[i];
|
||||||
if (typeof v === "string") {
|
if (typeof v === "string") {
|
||||||
s.add(v);
|
s.add(v);
|
||||||
} else if (v instanceof Int32Array) {
|
} else if (v instanceof Int32Array) {
|
||||||
s.add(new Uint8Array(v.buffer));
|
s.add(v);
|
||||||
} else {
|
} else {
|
||||||
s.add(v.toString());
|
s.add(v.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.digest()
|
return s.digest();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
type SparseArray<T = number> = (T | T[] | SparseArray<T>)[];
|
type SparseArray<T = number> = (T | T[] | SparseArray<T>)[];
|
||||||
|
|
||||||
export function concatEncodedArrays(input: (number | number[] | Int32Array)[]): Int32Array {
|
export function concatEncodedArrays(
|
||||||
|
input: (number | number[] | Int32Array)[],
|
||||||
|
): Int32Array {
|
||||||
let totalLength = 4;
|
let totalLength = 4;
|
||||||
for (let i = 0; i < input.length; i++) {
|
for (let i = 0; i < input.length; i++) {
|
||||||
const item = input[i];
|
const item = input[i];
|
||||||
@@ -36,7 +37,7 @@ export function concatEncodedArrays(input: (number | number[] | Int32Array)[]):
|
|||||||
result[totalLength - 2] = 1;
|
result[totalLength - 2] = 1;
|
||||||
result[totalLength - 1] = 1;
|
result[totalLength - 1] = 1;
|
||||||
|
|
||||||
return result
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encodes a nested array into a flat array with bracket and distance notation
|
// Encodes a nested array into a flat array with bracket and distance notation
|
||||||
@@ -68,12 +69,11 @@ export function encodeNestedArray(array: SparseArray): number[] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return [...encoded, 1, 1];
|
return [...encoded, 1, 1];
|
||||||
};
|
}
|
||||||
|
|
||||||
function decode_recursive(dense: number[] | Int32Array, index = 0) {
|
function decode_recursive(dense: number[] | Int32Array, index = 0) {
|
||||||
|
|
||||||
if (dense instanceof Int32Array) {
|
if (dense instanceof Int32Array) {
|
||||||
dense = Array.from(dense)
|
dense = Array.from(dense);
|
||||||
}
|
}
|
||||||
|
|
||||||
const decoded: (number | number[])[] = [];
|
const decoded: (number | number[])[] = [];
|
||||||
@@ -82,12 +82,17 @@ function decode_recursive(dense: number[] | Int32Array, index = 0) {
|
|||||||
index += 2; // Skip the initial bracket notation
|
index += 2; // Skip the initial bracket notation
|
||||||
while (index < dense.length) {
|
while (index < dense.length) {
|
||||||
if (index === nextBracketIndex) {
|
if (index === nextBracketIndex) {
|
||||||
if (dense[index] === 0) { // Opening bracket detected
|
if (dense[index] === 0) {
|
||||||
const [p, nextIndex, _nextBracketIndex] = decode_recursive(dense, index);
|
// Opening bracket detected
|
||||||
decoded.push(p);
|
const [p, nextIndex, _nextBracketIndex] = decode_recursive(
|
||||||
|
dense,
|
||||||
|
index,
|
||||||
|
);
|
||||||
|
decoded.push(...p);
|
||||||
index = nextIndex + 1;
|
index = nextIndex + 1;
|
||||||
nextBracketIndex = _nextBracketIndex;
|
nextBracketIndex = _nextBracketIndex;
|
||||||
} else { // Closing bracket detected
|
} else {
|
||||||
|
// Closing bracket detected
|
||||||
nextBracketIndex = dense[index + 1] + index + 1;
|
nextBracketIndex = dense[index + 1] + index + 1;
|
||||||
return [decoded, index, nextBracketIndex] as const;
|
return [decoded, index, nextBracketIndex] as const;
|
||||||
}
|
}
|
||||||
@@ -103,7 +108,6 @@ export function decodeNestedArray(dense: number[] | Int32Array) {
|
|||||||
return decode_recursive(dense, 0)[0];
|
return decode_recursive(dense, 0)[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export function splitNestedArray(input: Int32Array) {
|
export function splitNestedArray(input: Int32Array) {
|
||||||
let index = 0;
|
let index = 0;
|
||||||
const length = input.length;
|
const length = input.length;
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
|
//@ts-nocheck
|
||||||
import { NodeDefinition } from "@nodes/types";
|
import { NodeDefinition } from "@nodes/types";
|
||||||
|
|
||||||
const cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
|
const cachedTextDecoder = new TextDecoder("utf-8", {
|
||||||
|
ignoreBOM: true,
|
||||||
|
fatal: true,
|
||||||
|
});
|
||||||
const cachedTextEncoder = new TextEncoder();
|
const cachedTextEncoder = new TextEncoder();
|
||||||
|
|
||||||
|
const encodeString =
|
||||||
const encodeString = (typeof cachedTextEncoder.encodeInto === 'function'
|
typeof cachedTextEncoder.encodeInto === "function"
|
||||||
? function (arg, view) {
|
? function (arg, view) {
|
||||||
return cachedTextEncoder.encodeInto(arg, view);
|
return cachedTextEncoder.encodeInto(arg, view);
|
||||||
}
|
}
|
||||||
@@ -13,9 +17,9 @@ const encodeString = (typeof cachedTextEncoder.encodeInto === 'function'
|
|||||||
view.set(buf);
|
view.set(buf);
|
||||||
return {
|
return {
|
||||||
read: arg.length,
|
read: arg.length,
|
||||||
written: buf.length
|
written: buf.length,
|
||||||
|
};
|
||||||
};
|
};
|
||||||
});
|
|
||||||
|
|
||||||
function createWrapper() {
|
function createWrapper() {
|
||||||
let wasm: any;
|
let wasm: any;
|
||||||
@@ -53,7 +57,9 @@ function createWrapper() {
|
|||||||
return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len));
|
return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len));
|
||||||
}
|
}
|
||||||
|
|
||||||
function getObject(idx: number) { return heap[idx]; }
|
function getObject(idx: number) {
|
||||||
|
return heap[idx];
|
||||||
|
}
|
||||||
|
|
||||||
function addHeapObject(obj: any) {
|
function addHeapObject(obj: any) {
|
||||||
if (heap_next === heap.length) heap.push(heap.length + 1);
|
if (heap_next === heap.length) heap.push(heap.length + 1);
|
||||||
@@ -63,9 +69,11 @@ function createWrapper() {
|
|||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
let WASM_VECTOR_LEN = 0;
|
let WASM_VECTOR_LEN = 0;
|
||||||
function passArray32ToWasm0(arg: ArrayLike<number>, malloc: (arg0: number, arg1: number) => number) {
|
function passArray32ToWasm0(
|
||||||
|
arg: ArrayLike<number>,
|
||||||
|
malloc: (arg0: number, arg1: number) => number,
|
||||||
|
) {
|
||||||
const ptr = malloc(arg.length * 4, 4) >>> 0;
|
const ptr = malloc(arg.length * 4, 4) >>> 0;
|
||||||
getUint32Memory0().set(arg, ptr / 4);
|
getUint32Memory0().set(arg, ptr / 4);
|
||||||
WASM_VECTOR_LEN = arg.length;
|
WASM_VECTOR_LEN = arg.length;
|
||||||
@@ -89,21 +97,10 @@ function createWrapper() {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getArrayJsValueFromWasm0(ptr: number, len: number) {
|
|
||||||
ptr = ptr >>> 0;
|
|
||||||
const mem = getUint32Memory0();
|
|
||||||
const slice = mem.subarray(ptr / 4, ptr / 4 + len);
|
|
||||||
const result = [];
|
|
||||||
for (let i = 0; i < slice.length; i++) {
|
|
||||||
result.push(takeObject(slice[i]));
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function __wbindgen_string_new(arg0: number, arg1: number) {
|
function __wbindgen_string_new(arg0: number, arg1: number) {
|
||||||
const ret = getStringFromWasm0(arg0, arg1);
|
const ret = getStringFromWasm0(arg0, arg1);
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
}
|
||||||
|
|
||||||
// Additional methods and their internal helpers can also be refactored in a similar manner.
|
// Additional methods and their internal helpers can also be refactored in a similar manner.
|
||||||
function get_definition() {
|
function get_definition() {
|
||||||
@@ -124,7 +121,6 @@ function createWrapper() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function execute(args: Int32Array) {
|
function execute(args: Int32Array) {
|
||||||
try {
|
try {
|
||||||
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
||||||
@@ -141,12 +137,19 @@ function createWrapper() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function passStringToWasm0(arg: string, malloc: (arg0: any, arg1: number) => number, realloc: ((arg0: number, arg1: any, arg2: number, arg3: number) => number) | undefined) {
|
function passStringToWasm0(
|
||||||
|
arg: string,
|
||||||
|
malloc: (arg0: any, arg1: number) => number,
|
||||||
|
realloc:
|
||||||
|
| ((arg0: number, arg1: any, arg2: number, arg3: number) => number)
|
||||||
|
| undefined,
|
||||||
|
) {
|
||||||
if (realloc === undefined) {
|
if (realloc === undefined) {
|
||||||
const buf = cachedTextEncoder.encode(arg);
|
const buf = cachedTextEncoder.encode(arg);
|
||||||
const ptr = malloc(buf.length, 1) >>> 0;
|
const ptr = malloc(buf.length, 1) >>> 0;
|
||||||
getUint8Memory0().subarray(ptr, ptr + buf.length).set(buf);
|
getUint8Memory0()
|
||||||
|
.subarray(ptr, ptr + buf.length)
|
||||||
|
.set(buf);
|
||||||
WASM_VECTOR_LEN = buf.length;
|
WASM_VECTOR_LEN = buf.length;
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
@@ -160,7 +163,7 @@ function createWrapper() {
|
|||||||
|
|
||||||
for (; offset < len; offset++) {
|
for (; offset < len; offset++) {
|
||||||
const code = arg.charCodeAt(offset);
|
const code = arg.charCodeAt(offset);
|
||||||
if (code > 0x7F) break;
|
if (code > 0x7f) break;
|
||||||
mem[ptr + offset] = code;
|
mem[ptr + offset] = code;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,7 +171,7 @@ function createWrapper() {
|
|||||||
if (offset !== 0) {
|
if (offset !== 0) {
|
||||||
arg = arg.slice(offset);
|
arg = arg.slice(offset);
|
||||||
}
|
}
|
||||||
ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;
|
ptr = realloc(ptr, len, (len = offset + arg.length * 3), 1) >>> 0;
|
||||||
const view = getUint8Memory0().subarray(ptr + offset, ptr + len);
|
const view = getUint8Memory0().subarray(ptr + offset, ptr + len);
|
||||||
const ret = encodeString(arg, view);
|
const ret = encodeString(arg, view);
|
||||||
|
|
||||||
@@ -183,15 +186,19 @@ function createWrapper() {
|
|||||||
function __wbg_new_abda76e883ba8a5f() {
|
function __wbg_new_abda76e883ba8a5f() {
|
||||||
const ret = new Error();
|
const ret = new Error();
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
}
|
||||||
|
|
||||||
function __wbg_stack_658279fe44541cf6(arg0, arg1) {
|
function __wbg_stack_658279fe44541cf6(arg0, arg1) {
|
||||||
const ret = getObject(arg1).stack;
|
const ret = getObject(arg1).stack;
|
||||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr1 = passStringToWasm0(
|
||||||
|
ret,
|
||||||
|
wasm.__wbindgen_malloc,
|
||||||
|
wasm.__wbindgen_realloc,
|
||||||
|
);
|
||||||
const len1 = WASM_VECTOR_LEN;
|
const len1 = WASM_VECTOR_LEN;
|
||||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||||
};
|
}
|
||||||
|
|
||||||
function __wbg_error_f851667af71bcfc6(arg0, arg1) {
|
function __wbg_error_f851667af71bcfc6(arg0, arg1) {
|
||||||
let deferred0_0;
|
let deferred0_0;
|
||||||
@@ -203,27 +210,25 @@ function createWrapper() {
|
|||||||
} finally {
|
} finally {
|
||||||
wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
|
wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
|
|
||||||
function __wbindgen_object_drop_ref(arg0) {
|
function __wbindgen_object_drop_ref(arg0) {
|
||||||
takeObject(arg0);
|
takeObject(arg0);
|
||||||
};
|
}
|
||||||
|
|
||||||
function __wbg_log_5bb5f88f245d7762(arg0) {
|
function __wbg_log_5bb5f88f245d7762(arg0) {
|
||||||
console.log(getObject(arg0));
|
console.log(getObject(arg0));
|
||||||
};
|
}
|
||||||
|
|
||||||
function __wbindgen_throw(arg0, arg1) {
|
function __wbindgen_throw(arg0, arg1) {
|
||||||
throw new Error(getStringFromWasm0(arg0, arg1));
|
throw new Error(getStringFromWasm0(arg0, arg1));
|
||||||
};
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
setInstance(instance: WebAssembly.Instance) {
|
setInstance(instance: WebAssembly.Instance) {
|
||||||
wasm = instance.exports;
|
wasm = instance.exports;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
exports: {
|
exports: {
|
||||||
// Expose other methods that interact with the wasm instance
|
// Expose other methods that interact with the wasm instance
|
||||||
execute,
|
execute,
|
||||||
@@ -240,11 +245,12 @@ function createWrapper() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function createWasmWrapper(wasmBuffer: ArrayBuffer | Uint8Array) {
|
||||||
export function createWasmWrapper(wasmBuffer: ArrayBuffer) {
|
|
||||||
const wrapper = createWrapper();
|
const wrapper = createWrapper();
|
||||||
const module = new WebAssembly.Module(wasmBuffer);
|
const module = new WebAssembly.Module(wasmBuffer);
|
||||||
const instance = new WebAssembly.Instance(module, { ["./index_bg.js"]: wrapper });
|
const instance = new WebAssembly.Instance(module, {
|
||||||
|
["./index_bg.js"]: wrapper,
|
||||||
|
});
|
||||||
wrapper.setInstance(instance);
|
wrapper.setInstance(instance);
|
||||||
return wrapper.exports;
|
return wrapper.exports;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user