@timo9378/flow2code 0.1.6 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/dist/cli.js +54 -18
- package/dist/compiler.cjs +17 -12
- package/dist/compiler.js +17 -12
- package/dist/server.js +16 -12
- package/out/404.html +1 -1
- package/out/__next.__PAGE__.txt +2 -2
- package/out/__next._full.txt +2 -2
- package/out/__next._head.txt +1 -1
- package/out/__next._index.txt +1 -1
- package/out/__next._tree.txt +1 -1
- package/out/_next/static/chunks/{bfa275b7488d8b70.js → 2fd98ca28cbab9a6.js} +1 -1
- package/out/_next/static/chunks/4ce13068a7e61854.js +25 -0
- package/out/_next/static/chunks/{5f1a9fec0e69c483.js → fd3c7cf5ea219c74.js} +1 -1
- package/out/_not-found/__next._full.txt +1 -1
- package/out/_not-found/__next._head.txt +1 -1
- package/out/_not-found/__next._index.txt +1 -1
- package/out/_not-found/__next._not-found/__PAGE__.txt +1 -1
- package/out/_not-found/__next._not-found.txt +1 -1
- package/out/_not-found/__next._tree.txt +1 -1
- package/out/_not-found.html +1 -1
- package/out/_not-found.txt +1 -1
- package/out/index.html +2 -2
- package/out/index.txt +2 -2
- package/package.json +1 -1
- /package/out/_next/static/{wFX9tOZWtEdER7XrtbgHQ → 4eCLtLp-IPL1tppPGnHZE}/_buildManifest.js +0 -0
- /package/out/_next/static/{wFX9tOZWtEdER7XrtbgHQ → 4eCLtLp-IPL1tppPGnHZE}/_clientMiddlewareManifest.json +0 -0
- /package/out/_next/static/{wFX9tOZWtEdER7XrtbgHQ → 4eCLtLp-IPL1tppPGnHZE}/_ssgManifest.js +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,22 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
7
7
|
|
|
8
|
+
## [0.1.7] — 2026-03-05
|
|
9
|
+
|
|
10
|
+
### Performance
|
|
11
|
+
- **Precompute `edgeSuccessors` map** — Eliminated O(N×E) per-call rebuild in `generateBlockContinuation`; successor lookup is now O(1) via pre-built map in `CompilerContext`
|
|
12
|
+
- **Reuse `nodeMap` in control-flow analysis** — `computeControlFlowDescendants` now receives the existing `nodeMap` instead of rebuilding a redundant `new Map()` each call
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
- **Decompiler `processForStatement` AST correctness** — Replaced fragile `.split("{")` string hack with proper AST methods (`getInitializer()`, `getCondition()`, `getIncrementor()`); fixes incorrect parsing when loop body contains object literals
|
|
16
|
+
- **OpenAPI YAML import** — `handleImportOpenAPI` now supports `.yaml`/`.yml` files via dynamic `import("yaml")` instead of silently failing with `JSON.parse`
|
|
17
|
+
- **`revokeObjectURL` download race** — Deferred `URL.revokeObjectURL` by 10 seconds after `click()` to prevent Safari/slow-browser download failures
|
|
18
|
+
- **CLI watch mode async I/O** — New `loadFlowProjectAsync` reads flow projects with `fs/promises` (`readFile`/`readdir`); `compileFlowDirAsync` no longer blocks the event loop with sync file I/O
|
|
19
|
+
|
|
20
|
+
### Tests
|
|
21
|
+
- Added `loadFlowProjectAsync` parity tests (split + JSON + error case)
|
|
22
|
+
- Test count: 410 tests / 33 test files
|
|
23
|
+
|
|
8
24
|
## [0.1.6] — 2026-03-05
|
|
9
25
|
|
|
10
26
|
### Fixed (Critical)
|
package/dist/cli.js
CHANGED
|
@@ -1852,10 +1852,18 @@ function compile(ir, options) {
|
|
|
1852
1852
|
dagMode: false,
|
|
1853
1853
|
symbolTableExclusions: /* @__PURE__ */ new Set(),
|
|
1854
1854
|
generatedBlockNodeIds: /* @__PURE__ */ new Set(),
|
|
1855
|
-
pluginRegistry
|
|
1855
|
+
pluginRegistry,
|
|
1856
|
+
edgeSuccessors: (() => {
|
|
1857
|
+
const map = /* @__PURE__ */ new Map();
|
|
1858
|
+
for (const edge of workingIR.edges) {
|
|
1859
|
+
if (!map.has(edge.sourceNodeId)) map.set(edge.sourceNodeId, []);
|
|
1860
|
+
map.get(edge.sourceNodeId).push(edge.targetNodeId);
|
|
1861
|
+
}
|
|
1862
|
+
return map;
|
|
1863
|
+
})()
|
|
1856
1864
|
};
|
|
1857
1865
|
const trigger = workingIR.nodes.find((n) => n.category === "trigger" /* TRIGGER */);
|
|
1858
|
-
const preComputedBlockNodes = computeControlFlowDescendants(workingIR, trigger.id);
|
|
1866
|
+
const preComputedBlockNodes = computeControlFlowDescendants(workingIR, trigger.id, nodeMap);
|
|
1859
1867
|
for (const nodeId of preComputedBlockNodes) {
|
|
1860
1868
|
context.childBlockNodeIds.add(nodeId);
|
|
1861
1869
|
context.symbolTableExclusions.add(nodeId);
|
|
@@ -1935,8 +1943,7 @@ function isControlFlowEdge(edge, nodeMap) {
|
|
|
1935
1943
|
const controlPorts = CONTROL_FLOW_PORT_MAP[sourceNode.nodeType];
|
|
1936
1944
|
return controlPorts !== void 0 && controlPorts.has(edge.sourcePortId);
|
|
1937
1945
|
}
|
|
1938
|
-
function computeControlFlowDescendants(ir, triggerId) {
|
|
1939
|
-
const nodeMap = new Map(ir.nodes.map((n) => [n.id, n]));
|
|
1946
|
+
function computeControlFlowDescendants(ir, triggerId, nodeMap) {
|
|
1940
1947
|
const strippedSuccessors = /* @__PURE__ */ new Map();
|
|
1941
1948
|
for (const node of ir.nodes) {
|
|
1942
1949
|
strippedSuccessors.set(node.id, /* @__PURE__ */ new Set());
|
|
@@ -1969,13 +1976,7 @@ function computeControlFlowDescendants(ir, triggerId) {
|
|
|
1969
1976
|
function generateBlockContinuation(writer, fromNodeId, context) {
|
|
1970
1977
|
const reachable = /* @__PURE__ */ new Set();
|
|
1971
1978
|
const bfsQueue = [fromNodeId];
|
|
1972
|
-
const edgeSuccessors =
|
|
1973
|
-
for (const edge of context.ir.edges) {
|
|
1974
|
-
if (!edgeSuccessors.has(edge.sourceNodeId)) {
|
|
1975
|
-
edgeSuccessors.set(edge.sourceNodeId, []);
|
|
1976
|
-
}
|
|
1977
|
-
edgeSuccessors.get(edge.sourceNodeId).push(edge.targetNodeId);
|
|
1978
|
-
}
|
|
1979
|
+
const edgeSuccessors = context.edgeSuccessors;
|
|
1979
1980
|
while (bfsQueue.length > 0) {
|
|
1980
1981
|
const id = bfsQueue.shift();
|
|
1981
1982
|
if (reachable.has(id)) continue;
|
|
@@ -2764,7 +2765,10 @@ function processForInStatement(stmt, _prevNodeId, ctx, line) {
|
|
|
2764
2765
|
}
|
|
2765
2766
|
function processForStatement(stmt, _prevNodeId, ctx, line) {
|
|
2766
2767
|
const nodeId = ctx.nextId("loop");
|
|
2767
|
-
const
|
|
2768
|
+
const initText = stmt.getInitializer()?.getText() ?? "";
|
|
2769
|
+
const condText = stmt.getCondition()?.getText() ?? "";
|
|
2770
|
+
const incrText = stmt.getIncrementor()?.getText() ?? "";
|
|
2771
|
+
const fullText = `for (${initText}; ${condText}; ${incrText})`;
|
|
2768
2772
|
ctx.addNode({
|
|
2769
2773
|
id: nodeId,
|
|
2770
2774
|
nodeType: "for_loop" /* FOR_LOOP */,
|
|
@@ -3946,7 +3950,7 @@ __export(server_exports, {
|
|
|
3946
3950
|
startServer: () => startServer
|
|
3947
3951
|
});
|
|
3948
3952
|
import { createServer } from "http";
|
|
3949
|
-
import { readFile, stat } from "fs/promises";
|
|
3953
|
+
import { readFile as readFile2, stat } from "fs/promises";
|
|
3950
3954
|
import { join as join3, extname as extname2, dirname as dirname3, resolve as resolve2 } from "path";
|
|
3951
3955
|
import { fileURLToPath } from "url";
|
|
3952
3956
|
import { existsSync as existsSync3 } from "fs";
|
|
@@ -4044,7 +4048,7 @@ async function serveStatic(staticDir, pathname, res) {
|
|
|
4044
4048
|
if (!s.isFile()) return false;
|
|
4045
4049
|
const ext = extname2(filePath).toLowerCase();
|
|
4046
4050
|
const contentType = MIME_TYPES[ext] || "application/octet-stream";
|
|
4047
|
-
const content = await
|
|
4051
|
+
const content = await readFile2(filePath);
|
|
4048
4052
|
res.writeHead(200, { "Content-Type": contentType });
|
|
4049
4053
|
res.end(content);
|
|
4050
4054
|
return true;
|
|
@@ -4108,7 +4112,7 @@ async function handleRequest(req, res, staticDir, projectRoot) {
|
|
|
4108
4112
|
if (served) return;
|
|
4109
4113
|
const indexPath = join3(staticDir, "index.html");
|
|
4110
4114
|
try {
|
|
4111
|
-
const content = await
|
|
4115
|
+
const content = await readFile2(indexPath, "utf-8");
|
|
4112
4116
|
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
4113
4117
|
res.end(content);
|
|
4114
4118
|
} catch {
|
|
@@ -4190,7 +4194,7 @@ init_logger();
|
|
|
4190
4194
|
init_validator();
|
|
4191
4195
|
import { Command } from "commander";
|
|
4192
4196
|
import { readFileSync as readFileSync3, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3, existsSync as existsSync4, readdirSync as readdirSync2, rmSync as rmSync2 } from "fs";
|
|
4193
|
-
import { readFile as
|
|
4197
|
+
import { readFile as readFile3, writeFile, mkdir } from "fs/promises";
|
|
4194
4198
|
import { join as join4, dirname as dirname4, resolve as resolve3, basename as basename2 } from "path";
|
|
4195
4199
|
import { watch } from "chokidar";
|
|
4196
4200
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
@@ -4329,6 +4333,7 @@ function sanitizeFilename(id) {
|
|
|
4329
4333
|
|
|
4330
4334
|
// src/lib/storage/flow-project.ts
|
|
4331
4335
|
import { readFileSync, writeFileSync, mkdirSync, existsSync, readdirSync, rmSync, statSync } from "fs";
|
|
4336
|
+
import { readFile, readdir } from "fs/promises";
|
|
4332
4337
|
import { join, dirname } from "path";
|
|
4333
4338
|
function detectFormat(inputPath) {
|
|
4334
4339
|
if (inputPath.endsWith(".flow.json") && existsSync(inputPath)) {
|
|
@@ -4379,6 +4384,37 @@ function loadFlowProject(inputPath) {
|
|
|
4379
4384
|
const ir = mergeIR({ meta, edges, nodes });
|
|
4380
4385
|
return { path: resolvedPath, format, ir };
|
|
4381
4386
|
}
|
|
4387
|
+
async function loadFlowProjectAsync(inputPath) {
|
|
4388
|
+
const { resolvedPath, format } = detectFormat(inputPath);
|
|
4389
|
+
if (format === "json") {
|
|
4390
|
+
if (!existsSync(resolvedPath)) {
|
|
4391
|
+
throw new Error(`Flow file not found: ${resolvedPath}`);
|
|
4392
|
+
}
|
|
4393
|
+
const raw = await readFile(resolvedPath, "utf-8");
|
|
4394
|
+
const ir2 = JSON.parse(raw);
|
|
4395
|
+
return { path: resolvedPath, format, ir: ir2 };
|
|
4396
|
+
}
|
|
4397
|
+
if (!existsSync(resolvedPath)) {
|
|
4398
|
+
throw new Error(`Flow directory not found: ${resolvedPath}`);
|
|
4399
|
+
}
|
|
4400
|
+
const metaPath = join(resolvedPath, "meta.yaml");
|
|
4401
|
+
if (!existsSync(metaPath)) {
|
|
4402
|
+
throw new Error(`meta.yaml not found in ${resolvedPath} \u2014 not a valid Flow directory`);
|
|
4403
|
+
}
|
|
4404
|
+
const meta = await readFile(metaPath, "utf-8");
|
|
4405
|
+
const edgesPath = join(resolvedPath, "edges.yaml");
|
|
4406
|
+
const edges = existsSync(edgesPath) ? await readFile(edgesPath, "utf-8") : "";
|
|
4407
|
+
const nodesDir = join(resolvedPath, "nodes");
|
|
4408
|
+
const nodes = /* @__PURE__ */ new Map();
|
|
4409
|
+
if (existsSync(nodesDir)) {
|
|
4410
|
+
const nodeFiles = (await readdir(nodesDir)).filter((f) => f.endsWith(".yaml"));
|
|
4411
|
+
for (const file of nodeFiles) {
|
|
4412
|
+
nodes.set(file, await readFile(join(nodesDir, file), "utf-8"));
|
|
4413
|
+
}
|
|
4414
|
+
}
|
|
4415
|
+
const ir = mergeIR({ meta, edges, nodes });
|
|
4416
|
+
return { path: resolvedPath, format, ir };
|
|
4417
|
+
}
|
|
4382
4418
|
function saveFlowProject(ir, outputPath, options = {}) {
|
|
4383
4419
|
const { format = "split", cleanOrphanNodes = true } = options;
|
|
4384
4420
|
if (format === "json") {
|
|
@@ -5310,7 +5346,7 @@ function generateEnvExample() {
|
|
|
5310
5346
|
async function compileFileAsync(filePath, projectRoot) {
|
|
5311
5347
|
const startTime = Date.now();
|
|
5312
5348
|
try {
|
|
5313
|
-
const raw = await
|
|
5349
|
+
const raw = await readFile3(filePath, "utf-8");
|
|
5314
5350
|
const ir = JSON.parse(raw);
|
|
5315
5351
|
const validation = validateFlowIR(ir);
|
|
5316
5352
|
if (!validation.valid) {
|
|
@@ -5345,7 +5381,7 @@ async function compileFileAsync(filePath, projectRoot) {
|
|
|
5345
5381
|
async function compileFlowDirAsync(dirPath, projectRoot) {
|
|
5346
5382
|
const startTime = Date.now();
|
|
5347
5383
|
try {
|
|
5348
|
-
const project =
|
|
5384
|
+
const project = await loadFlowProjectAsync(dirPath);
|
|
5349
5385
|
const ir = project.ir;
|
|
5350
5386
|
const validation = validateFlowIR(ir);
|
|
5351
5387
|
if (!validation.valid) {
|
package/dist/compiler.cjs
CHANGED
|
@@ -1861,10 +1861,18 @@ function compile(ir, options) {
|
|
|
1861
1861
|
dagMode: false,
|
|
1862
1862
|
symbolTableExclusions: /* @__PURE__ */ new Set(),
|
|
1863
1863
|
generatedBlockNodeIds: /* @__PURE__ */ new Set(),
|
|
1864
|
-
pluginRegistry
|
|
1864
|
+
pluginRegistry,
|
|
1865
|
+
edgeSuccessors: (() => {
|
|
1866
|
+
const map = /* @__PURE__ */ new Map();
|
|
1867
|
+
for (const edge of workingIR.edges) {
|
|
1868
|
+
if (!map.has(edge.sourceNodeId)) map.set(edge.sourceNodeId, []);
|
|
1869
|
+
map.get(edge.sourceNodeId).push(edge.targetNodeId);
|
|
1870
|
+
}
|
|
1871
|
+
return map;
|
|
1872
|
+
})()
|
|
1865
1873
|
};
|
|
1866
1874
|
const trigger = workingIR.nodes.find((n) => n.category === "trigger" /* TRIGGER */);
|
|
1867
|
-
const preComputedBlockNodes = computeControlFlowDescendants(workingIR, trigger.id);
|
|
1875
|
+
const preComputedBlockNodes = computeControlFlowDescendants(workingIR, trigger.id, nodeMap);
|
|
1868
1876
|
for (const nodeId of preComputedBlockNodes) {
|
|
1869
1877
|
context.childBlockNodeIds.add(nodeId);
|
|
1870
1878
|
context.symbolTableExclusions.add(nodeId);
|
|
@@ -1949,8 +1957,7 @@ function isControlFlowEdge(edge, nodeMap) {
|
|
|
1949
1957
|
const controlPorts = CONTROL_FLOW_PORT_MAP[sourceNode.nodeType];
|
|
1950
1958
|
return controlPorts !== void 0 && controlPorts.has(edge.sourcePortId);
|
|
1951
1959
|
}
|
|
1952
|
-
function computeControlFlowDescendants(ir, triggerId) {
|
|
1953
|
-
const nodeMap = new Map(ir.nodes.map((n) => [n.id, n]));
|
|
1960
|
+
function computeControlFlowDescendants(ir, triggerId, nodeMap) {
|
|
1954
1961
|
const strippedSuccessors = /* @__PURE__ */ new Map();
|
|
1955
1962
|
for (const node of ir.nodes) {
|
|
1956
1963
|
strippedSuccessors.set(node.id, /* @__PURE__ */ new Set());
|
|
@@ -1983,13 +1990,7 @@ function computeControlFlowDescendants(ir, triggerId) {
|
|
|
1983
1990
|
function generateBlockContinuation(writer, fromNodeId, context) {
|
|
1984
1991
|
const reachable = /* @__PURE__ */ new Set();
|
|
1985
1992
|
const bfsQueue = [fromNodeId];
|
|
1986
|
-
const edgeSuccessors =
|
|
1987
|
-
for (const edge of context.ir.edges) {
|
|
1988
|
-
if (!edgeSuccessors.has(edge.sourceNodeId)) {
|
|
1989
|
-
edgeSuccessors.set(edge.sourceNodeId, []);
|
|
1990
|
-
}
|
|
1991
|
-
edgeSuccessors.get(edge.sourceNodeId).push(edge.targetNodeId);
|
|
1992
|
-
}
|
|
1993
|
+
const edgeSuccessors = context.edgeSuccessors;
|
|
1993
1994
|
while (bfsQueue.length > 0) {
|
|
1994
1995
|
const id = bfsQueue.shift();
|
|
1995
1996
|
if (reachable.has(id)) continue;
|
|
@@ -2818,7 +2819,10 @@ function processForInStatement(stmt, _prevNodeId, ctx, line) {
|
|
|
2818
2819
|
}
|
|
2819
2820
|
function processForStatement(stmt, _prevNodeId, ctx, line) {
|
|
2820
2821
|
const nodeId = ctx.nextId("loop");
|
|
2821
|
-
const
|
|
2822
|
+
const initText = stmt.getInitializer()?.getText() ?? "";
|
|
2823
|
+
const condText = stmt.getCondition()?.getText() ?? "";
|
|
2824
|
+
const incrText = stmt.getIncrementor()?.getText() ?? "";
|
|
2825
|
+
const fullText = `for (${initText}; ${condText}; ${incrText})`;
|
|
2822
2826
|
ctx.addNode({
|
|
2823
2827
|
id: nodeId,
|
|
2824
2828
|
nodeType: "for_loop" /* FOR_LOOP */,
|
|
@@ -3767,6 +3771,7 @@ function sanitizeFilename(id) {
|
|
|
3767
3771
|
|
|
3768
3772
|
// src/lib/storage/flow-project.ts
|
|
3769
3773
|
var import_node_fs = require("fs");
|
|
3774
|
+
var import_promises = require("fs/promises");
|
|
3770
3775
|
var import_node_path = require("path");
|
|
3771
3776
|
function detectFormat(inputPath) {
|
|
3772
3777
|
if (inputPath.endsWith(".flow.json") && (0, import_node_fs.existsSync)(inputPath)) {
|
package/dist/compiler.js
CHANGED
|
@@ -1794,10 +1794,18 @@ function compile(ir, options) {
|
|
|
1794
1794
|
dagMode: false,
|
|
1795
1795
|
symbolTableExclusions: /* @__PURE__ */ new Set(),
|
|
1796
1796
|
generatedBlockNodeIds: /* @__PURE__ */ new Set(),
|
|
1797
|
-
pluginRegistry
|
|
1797
|
+
pluginRegistry,
|
|
1798
|
+
edgeSuccessors: (() => {
|
|
1799
|
+
const map = /* @__PURE__ */ new Map();
|
|
1800
|
+
for (const edge of workingIR.edges) {
|
|
1801
|
+
if (!map.has(edge.sourceNodeId)) map.set(edge.sourceNodeId, []);
|
|
1802
|
+
map.get(edge.sourceNodeId).push(edge.targetNodeId);
|
|
1803
|
+
}
|
|
1804
|
+
return map;
|
|
1805
|
+
})()
|
|
1798
1806
|
};
|
|
1799
1807
|
const trigger = workingIR.nodes.find((n) => n.category === "trigger" /* TRIGGER */);
|
|
1800
|
-
const preComputedBlockNodes = computeControlFlowDescendants(workingIR, trigger.id);
|
|
1808
|
+
const preComputedBlockNodes = computeControlFlowDescendants(workingIR, trigger.id, nodeMap);
|
|
1801
1809
|
for (const nodeId of preComputedBlockNodes) {
|
|
1802
1810
|
context.childBlockNodeIds.add(nodeId);
|
|
1803
1811
|
context.symbolTableExclusions.add(nodeId);
|
|
@@ -1882,8 +1890,7 @@ function isControlFlowEdge(edge, nodeMap) {
|
|
|
1882
1890
|
const controlPorts = CONTROL_FLOW_PORT_MAP[sourceNode.nodeType];
|
|
1883
1891
|
return controlPorts !== void 0 && controlPorts.has(edge.sourcePortId);
|
|
1884
1892
|
}
|
|
1885
|
-
function computeControlFlowDescendants(ir, triggerId) {
|
|
1886
|
-
const nodeMap = new Map(ir.nodes.map((n) => [n.id, n]));
|
|
1893
|
+
function computeControlFlowDescendants(ir, triggerId, nodeMap) {
|
|
1887
1894
|
const strippedSuccessors = /* @__PURE__ */ new Map();
|
|
1888
1895
|
for (const node of ir.nodes) {
|
|
1889
1896
|
strippedSuccessors.set(node.id, /* @__PURE__ */ new Set());
|
|
@@ -1916,13 +1923,7 @@ function computeControlFlowDescendants(ir, triggerId) {
|
|
|
1916
1923
|
function generateBlockContinuation(writer, fromNodeId, context) {
|
|
1917
1924
|
const reachable = /* @__PURE__ */ new Set();
|
|
1918
1925
|
const bfsQueue = [fromNodeId];
|
|
1919
|
-
const edgeSuccessors =
|
|
1920
|
-
for (const edge of context.ir.edges) {
|
|
1921
|
-
if (!edgeSuccessors.has(edge.sourceNodeId)) {
|
|
1922
|
-
edgeSuccessors.set(edge.sourceNodeId, []);
|
|
1923
|
-
}
|
|
1924
|
-
edgeSuccessors.get(edge.sourceNodeId).push(edge.targetNodeId);
|
|
1925
|
-
}
|
|
1926
|
+
const edgeSuccessors = context.edgeSuccessors;
|
|
1926
1927
|
while (bfsQueue.length > 0) {
|
|
1927
1928
|
const id = bfsQueue.shift();
|
|
1928
1929
|
if (reachable.has(id)) continue;
|
|
@@ -2754,7 +2755,10 @@ function processForInStatement(stmt, _prevNodeId, ctx, line) {
|
|
|
2754
2755
|
}
|
|
2755
2756
|
function processForStatement(stmt, _prevNodeId, ctx, line) {
|
|
2756
2757
|
const nodeId = ctx.nextId("loop");
|
|
2757
|
-
const
|
|
2758
|
+
const initText = stmt.getInitializer()?.getText() ?? "";
|
|
2759
|
+
const condText = stmt.getCondition()?.getText() ?? "";
|
|
2760
|
+
const incrText = stmt.getIncrementor()?.getText() ?? "";
|
|
2761
|
+
const fullText = `for (${initText}; ${condText}; ${incrText})`;
|
|
2758
2762
|
ctx.addNode({
|
|
2759
2763
|
id: nodeId,
|
|
2760
2764
|
nodeType: "for_loop" /* FOR_LOOP */,
|
|
@@ -3703,6 +3707,7 @@ function sanitizeFilename(id) {
|
|
|
3703
3707
|
|
|
3704
3708
|
// src/lib/storage/flow-project.ts
|
|
3705
3709
|
import { readFileSync, writeFileSync, mkdirSync, existsSync, readdirSync, rmSync, statSync } from "fs";
|
|
3710
|
+
import { readFile, readdir } from "fs/promises";
|
|
3706
3711
|
import { join, dirname } from "path";
|
|
3707
3712
|
function detectFormat(inputPath) {
|
|
3708
3713
|
if (inputPath.endsWith(".flow.json") && existsSync(inputPath)) {
|
package/dist/server.js
CHANGED
|
@@ -1747,10 +1747,18 @@ function compile(ir, options) {
|
|
|
1747
1747
|
dagMode: false,
|
|
1748
1748
|
symbolTableExclusions: /* @__PURE__ */ new Set(),
|
|
1749
1749
|
generatedBlockNodeIds: /* @__PURE__ */ new Set(),
|
|
1750
|
-
pluginRegistry
|
|
1750
|
+
pluginRegistry,
|
|
1751
|
+
edgeSuccessors: (() => {
|
|
1752
|
+
const map = /* @__PURE__ */ new Map();
|
|
1753
|
+
for (const edge of workingIR.edges) {
|
|
1754
|
+
if (!map.has(edge.sourceNodeId)) map.set(edge.sourceNodeId, []);
|
|
1755
|
+
map.get(edge.sourceNodeId).push(edge.targetNodeId);
|
|
1756
|
+
}
|
|
1757
|
+
return map;
|
|
1758
|
+
})()
|
|
1751
1759
|
};
|
|
1752
1760
|
const trigger = workingIR.nodes.find((n) => n.category === "trigger" /* TRIGGER */);
|
|
1753
|
-
const preComputedBlockNodes = computeControlFlowDescendants(workingIR, trigger.id);
|
|
1761
|
+
const preComputedBlockNodes = computeControlFlowDescendants(workingIR, trigger.id, nodeMap);
|
|
1754
1762
|
for (const nodeId of preComputedBlockNodes) {
|
|
1755
1763
|
context.childBlockNodeIds.add(nodeId);
|
|
1756
1764
|
context.symbolTableExclusions.add(nodeId);
|
|
@@ -1835,8 +1843,7 @@ function isControlFlowEdge(edge, nodeMap) {
|
|
|
1835
1843
|
const controlPorts = CONTROL_FLOW_PORT_MAP[sourceNode.nodeType];
|
|
1836
1844
|
return controlPorts !== void 0 && controlPorts.has(edge.sourcePortId);
|
|
1837
1845
|
}
|
|
1838
|
-
function computeControlFlowDescendants(ir, triggerId) {
|
|
1839
|
-
const nodeMap = new Map(ir.nodes.map((n) => [n.id, n]));
|
|
1846
|
+
function computeControlFlowDescendants(ir, triggerId, nodeMap) {
|
|
1840
1847
|
const strippedSuccessors = /* @__PURE__ */ new Map();
|
|
1841
1848
|
for (const node of ir.nodes) {
|
|
1842
1849
|
strippedSuccessors.set(node.id, /* @__PURE__ */ new Set());
|
|
@@ -1869,13 +1876,7 @@ function computeControlFlowDescendants(ir, triggerId) {
|
|
|
1869
1876
|
function generateBlockContinuation(writer, fromNodeId, context) {
|
|
1870
1877
|
const reachable = /* @__PURE__ */ new Set();
|
|
1871
1878
|
const bfsQueue = [fromNodeId];
|
|
1872
|
-
const edgeSuccessors =
|
|
1873
|
-
for (const edge of context.ir.edges) {
|
|
1874
|
-
if (!edgeSuccessors.has(edge.sourceNodeId)) {
|
|
1875
|
-
edgeSuccessors.set(edge.sourceNodeId, []);
|
|
1876
|
-
}
|
|
1877
|
-
edgeSuccessors.get(edge.sourceNodeId).push(edge.targetNodeId);
|
|
1878
|
-
}
|
|
1879
|
+
const edgeSuccessors = context.edgeSuccessors;
|
|
1879
1880
|
while (bfsQueue.length > 0) {
|
|
1880
1881
|
const id = bfsQueue.shift();
|
|
1881
1882
|
if (reachable.has(id)) continue;
|
|
@@ -2567,7 +2568,10 @@ function processForInStatement(stmt, _prevNodeId, ctx, line) {
|
|
|
2567
2568
|
}
|
|
2568
2569
|
function processForStatement(stmt, _prevNodeId, ctx, line) {
|
|
2569
2570
|
const nodeId = ctx.nextId("loop");
|
|
2570
|
-
const
|
|
2571
|
+
const initText = stmt.getInitializer()?.getText() ?? "";
|
|
2572
|
+
const condText = stmt.getCondition()?.getText() ?? "";
|
|
2573
|
+
const incrText = stmt.getIncrementor()?.getText() ?? "";
|
|
2574
|
+
const fullText = `for (${initText}; ${condText}; ${incrText})`;
|
|
2571
2575
|
ctx.addNode({
|
|
2572
2576
|
id: nodeId,
|
|
2573
2577
|
nodeType: "for_loop" /* FOR_LOOP */,
|
package/out/404.html
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><!--
|
|
1
|
+
<!DOCTYPE html><!--4eCLtLp_IPL1tppPGnHZE--><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="/_next/static/chunks/83ab8820627f8bfe.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/b6e8711267bccbbd.js"/><script src="/_next/static/chunks/fbca595129527827.js" async=""></script><script src="/_next/static/chunks/ab8888d4b78b94be.js" async=""></script><script src="/_next/static/chunks/turbopack-576234c945ffdc44.js" async=""></script><script src="/_next/static/chunks/acf223168ac429f7.js" async=""></script><script src="/_next/static/chunks/b163b5d7cccbcf42.js" async=""></script><script src="/_next/static/chunks/6b84376656bd9887.js" async=""></script><script src="/_next/static/chunks/b112c2f519e4b429.js" async=""></script><meta name="robots" content="noindex"/><title>404: This page could not be found.</title><title>Flow2Code | Visual AST Compiler</title><meta name="description" content="Visual backend logic generator: compile canvas nodes directly into native TypeScript code"/><link rel="manifest" href="/site.webmanifest"/><link rel="icon" href="/favicon.ico" sizes="any"/><link rel="icon" href="/favicon-16x16.png" sizes="16x16" type="image/png"/><link rel="icon" href="/favicon-32x32.png" sizes="32x32" type="image/png"/><link rel="apple-touch-icon" href="/apple-touch-icon.png"/><script src="/_next/static/chunks/a6dad97d9634a72d.js" noModule=""></script></head><body class="antialiased overflow-hidden"><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding:0 23px 0 0;font-size:24px;font-weight:500;vertical-align:top;line-height:49px">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:49px;margin:0">This page could not be found.</h2></div></div></div><!--$--><!--/$--><script src="/_next/static/chunks/b6e8711267bccbbd.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[46798,[\"/_next/static/chunks/acf223168ac429f7.js\"],\"TooltipProvider\"]\n3:I[95731,[\"/_next/static/chunks/b163b5d7cccbcf42.js\",\"/_next/static/chunks/6b84376656bd9887.js\"],\"default\"]\n4:I[58298,[\"/_next/static/chunks/acf223168ac429f7.js\",\"/_next/static/chunks/b112c2f519e4b429.js\"],\"default\"]\n5:I[32294,[\"/_next/static/chunks/b163b5d7cccbcf42.js\",\"/_next/static/chunks/6b84376656bd9887.js\"],\"default\"]\n6:I[5806,[\"/_next/static/chunks/b163b5d7cccbcf42.js\",\"/_next/static/chunks/6b84376656bd9887.js\"],\"OutletBoundary\"]\n7:\"$Sreact.suspense\"\n9:I[5806,[\"/_next/static/chunks/b163b5d7cccbcf42.js\",\"/_next/static/chunks/6b84376656bd9887.js\"],\"ViewportBoundary\"]\nb:I[5806,[\"/_next/static/chunks/b163b5d7cccbcf42.js\",\"/_next/static/chunks/6b84376656bd9887.js\"],\"MetadataBoundary\"]\nd:I[63491,[\"/_next/static/chunks/b163b5d7cccbcf42.js\",\"/_next/static/chunks/6b84376656bd9887.js\"],\"default\"]\n:HL[\"/_next/static/chunks/83ab8820627f8bfe.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"4eCLtLp-IPL1tppPGnHZE\",\"c\":[\"\",\"_not-found\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",true],[[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/83ab8820627f8bfe.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/acf223168ac429f7.js\",\"async\":true,\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"children\":[\"$\",\"body\",null,{\"className\":\"antialiased overflow-hidden\",\"children\":[\"$\",\"$L2\",null,{\"delayDuration\":200,\"children\":[\"$\",\"$L3\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$4\",\"errorStyles\":[],\"errorScripts\":[[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/b112c2f519e4b429.js\",\"async\":true}]],\"template\":[\"$\",\"$L5\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":404}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],[]],\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]}]}]}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L3\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L5\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":\"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:notFound:0:1:props:style\",\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":\"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:1:props:style\",\"children\":404}],[\"$\",\"div\",null,{\"style\":\"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:2:props:style\",\"children\":[\"$\",\"h2\",null,{\"style\":\"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:2:props:children:props:style\",\"children\":\"This page could not be found.\"}]}]]}]}]],null,[\"$\",\"$L6\",null,{\"children\":[\"$\",\"$7\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@8\"}]}]]}],{},null,false,false]},null,false,false]},null,false,false],[\"$\",\"$1\",\"h\",{\"children\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],[\"$\",\"$L9\",null,{\"children\":\"$La\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$Lb\",null,{\"children\":[\"$\",\"$7\",null,{\"name\":\"Next.Metadata\",\"children\":\"$Lc\"}]}]}],null]}],false]],\"m\":\"$undefined\",\"G\":[\"$d\",[]],\"S\":true}\n"])</script><script>self.__next_f.push([1,"a:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"e:I[22192,[\"/_next/static/chunks/b163b5d7cccbcf42.js\",\"/_next/static/chunks/6b84376656bd9887.js\"],\"IconMark\"]\n8:null\nc:[[\"$\",\"title\",\"0\",{\"children\":\"Flow2Code | Visual AST Compiler\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"Visual backend logic generator: compile canvas nodes directly into native TypeScript code\"}],[\"$\",\"link\",\"2\",{\"rel\":\"manifest\",\"href\":\"/site.webmanifest\",\"crossOrigin\":\"$undefined\"}],[\"$\",\"link\",\"3\",{\"rel\":\"icon\",\"href\":\"/favicon.ico\",\"sizes\":\"any\"}],[\"$\",\"link\",\"4\",{\"rel\":\"icon\",\"href\":\"/favicon-16x16.png\",\"sizes\":\"16x16\",\"type\":\"image/png\"}],[\"$\",\"link\",\"5\",{\"rel\":\"icon\",\"href\":\"/favicon-32x32.png\",\"sizes\":\"32x32\",\"type\":\"image/png\"}],[\"$\",\"link\",\"6\",{\"rel\":\"apple-touch-icon\",\"href\":\"/apple-touch-icon.png\"}],[\"$\",\"$Le\",\"7\",{}]]\n"])</script></body></html>
|
package/out/__next.__PAGE__.txt
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
1:"$Sreact.fragment"
|
|
2
2
|
2:I[55026,["/_next/static/chunks/b163b5d7cccbcf42.js","/_next/static/chunks/6b84376656bd9887.js"],"ClientPageRoot"]
|
|
3
|
-
3:I[52683,["/_next/static/chunks/acf223168ac429f7.js","/_next/static/chunks/
|
|
3
|
+
3:I[52683,["/_next/static/chunks/acf223168ac429f7.js","/_next/static/chunks/fd3c7cf5ea219c74.js","/_next/static/chunks/2fd98ca28cbab9a6.js"],"default"]
|
|
4
4
|
6:I[5806,["/_next/static/chunks/b163b5d7cccbcf42.js","/_next/static/chunks/6b84376656bd9887.js"],"OutletBoundary"]
|
|
5
5
|
7:"$Sreact.suspense"
|
|
6
6
|
:HL["/_next/static/chunks/8a5bd6fe3abc8091.css","style"]
|
|
7
|
-
0:{"buildId":"
|
|
7
|
+
0:{"buildId":"4eCLtLp-IPL1tppPGnHZE","rsc":["$","$1","c",{"children":[["$","$L2",null,{"Component":"$3","serverProvidedParams":{"searchParams":{},"params":{},"promises":["$@4","$@5"]}}],[["$","link","0",{"rel":"stylesheet","href":"/_next/static/chunks/8a5bd6fe3abc8091.css","precedence":"next"}],["$","script","script-0",{"src":"/_next/static/chunks/fd3c7cf5ea219c74.js","async":true}],["$","script","script-1",{"src":"/_next/static/chunks/2fd98ca28cbab9a6.js","async":true}]],["$","$L6",null,{"children":["$","$7",null,{"name":"Next.MetadataOutlet","children":"$@8"}]}]]}],"loading":null,"isPartial":false}
|
|
8
8
|
4:{}
|
|
9
9
|
5:"$0:rsc:props:children:0:props:serverProvidedParams:params"
|
|
10
10
|
8:null
|
package/out/__next._full.txt
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
4:I[58298,["/_next/static/chunks/acf223168ac429f7.js","/_next/static/chunks/b112c2f519e4b429.js"],"default"]
|
|
5
5
|
5:I[32294,["/_next/static/chunks/b163b5d7cccbcf42.js","/_next/static/chunks/6b84376656bd9887.js"],"default"]
|
|
6
6
|
6:I[55026,["/_next/static/chunks/b163b5d7cccbcf42.js","/_next/static/chunks/6b84376656bd9887.js"],"ClientPageRoot"]
|
|
7
|
-
7:I[52683,["/_next/static/chunks/acf223168ac429f7.js","/_next/static/chunks/
|
|
7
|
+
7:I[52683,["/_next/static/chunks/acf223168ac429f7.js","/_next/static/chunks/fd3c7cf5ea219c74.js","/_next/static/chunks/2fd98ca28cbab9a6.js"],"default"]
|
|
8
8
|
a:I[5806,["/_next/static/chunks/b163b5d7cccbcf42.js","/_next/static/chunks/6b84376656bd9887.js"],"OutletBoundary"]
|
|
9
9
|
b:"$Sreact.suspense"
|
|
10
10
|
d:I[5806,["/_next/static/chunks/b163b5d7cccbcf42.js","/_next/static/chunks/6b84376656bd9887.js"],"ViewportBoundary"]
|
|
@@ -12,7 +12,7 @@ f:I[5806,["/_next/static/chunks/b163b5d7cccbcf42.js","/_next/static/chunks/6b843
|
|
|
12
12
|
11:I[63491,["/_next/static/chunks/b163b5d7cccbcf42.js","/_next/static/chunks/6b84376656bd9887.js"],"default"]
|
|
13
13
|
:HL["/_next/static/chunks/83ab8820627f8bfe.css","style"]
|
|
14
14
|
:HL["/_next/static/chunks/8a5bd6fe3abc8091.css","style"]
|
|
15
|
-
0:{"P":null,"b":"
|
|
15
|
+
0:{"P":null,"b":"4eCLtLp-IPL1tppPGnHZE","c":["",""],"q":"","i":false,"f":[[["",{"children":["__PAGE__",{}]},"$undefined","$undefined",true],[["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/chunks/83ab8820627f8bfe.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","script","script-0",{"src":"/_next/static/chunks/acf223168ac429f7.js","async":true,"nonce":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"antialiased overflow-hidden","children":["$","$L2",null,{"delayDuration":200,"children":["$","$L3",null,{"parallelRouterKey":"children","error":"$4","errorStyles":[],"errorScripts":[["$","script","script-0",{"src":"/_next/static/chunks/b112c2f519e4b429.js","async":true}]],"template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}]}]}]}]]}],{"children":[["$","$1","c",{"children":[["$","$L6",null,{"Component":"$7","serverProvidedParams":{"searchParams":{},"params":{},"promises":["$@8","$@9"]}}],[["$","link","0",{"rel":"stylesheet","href":"/_next/static/chunks/8a5bd6fe3abc8091.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","script","script-0",{"src":"/_next/static/chunks/fd3c7cf5ea219c74.js","async":true,"nonce":"$undefined"}],["$","script","script-1",{"src":"/_next/static/chunks/2fd98ca28cbab9a6.js","async":true,"nonce":"$undefined"}]],["$","$La",null,{"children":["$","$b",null,{"name":"Next.MetadataOutlet","children":"$@c"}]}]]}],{},null,false,false]},null,false,false],["$","$1","h",{"children":[null,["$","$Ld",null,{"children":"$Le"}],["$","div",null,{"hidden":true,"children":["$","$Lf",null,{"children":["$","$b",null,{"name":"Next.Metadata","children":"$L10"}]}]}],null]}],false]],"m":"$undefined","G":["$11",[]],"S":true}
|
|
16
16
|
8:{}
|
|
17
17
|
9:"$0:f:0:1:1:children:0:props:children:0:props:serverProvidedParams:params"
|
|
18
18
|
e:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]
|
package/out/__next._head.txt
CHANGED
|
@@ -3,4 +3,4 @@
|
|
|
3
3
|
3:I[5806,["/_next/static/chunks/b163b5d7cccbcf42.js","/_next/static/chunks/6b84376656bd9887.js"],"MetadataBoundary"]
|
|
4
4
|
4:"$Sreact.suspense"
|
|
5
5
|
5:I[22192,["/_next/static/chunks/b163b5d7cccbcf42.js","/_next/static/chunks/6b84376656bd9887.js"],"IconMark"]
|
|
6
|
-
0:{"buildId":"
|
|
6
|
+
0:{"buildId":"4eCLtLp-IPL1tppPGnHZE","rsc":["$","$1","h",{"children":[null,["$","$L2",null,{"children":[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]}],["$","div",null,{"hidden":true,"children":["$","$L3",null,{"children":["$","$4",null,{"name":"Next.Metadata","children":[["$","title","0",{"children":"Flow2Code | Visual AST Compiler"}],["$","meta","1",{"name":"description","content":"Visual backend logic generator: compile canvas nodes directly into native TypeScript code"}],["$","link","2",{"rel":"manifest","href":"/site.webmanifest"}],["$","link","3",{"rel":"icon","href":"/favicon.ico","sizes":"any"}],["$","link","4",{"rel":"icon","href":"/favicon-16x16.png","sizes":"16x16","type":"image/png"}],["$","link","5",{"rel":"icon","href":"/favicon-32x32.png","sizes":"32x32","type":"image/png"}],["$","link","6",{"rel":"apple-touch-icon","href":"/apple-touch-icon.png"}],["$","$L5","7",{}]]}]}]}],null]}],"loading":null,"isPartial":false}
|
package/out/__next._index.txt
CHANGED
|
@@ -4,4 +4,4 @@
|
|
|
4
4
|
4:I[58298,["/_next/static/chunks/acf223168ac429f7.js","/_next/static/chunks/b112c2f519e4b429.js"],"default"]
|
|
5
5
|
5:I[32294,["/_next/static/chunks/b163b5d7cccbcf42.js","/_next/static/chunks/6b84376656bd9887.js"],"default"]
|
|
6
6
|
:HL["/_next/static/chunks/83ab8820627f8bfe.css","style"]
|
|
7
|
-
0:{"buildId":"
|
|
7
|
+
0:{"buildId":"4eCLtLp-IPL1tppPGnHZE","rsc":["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/chunks/83ab8820627f8bfe.css","precedence":"next"}],["$","script","script-0",{"src":"/_next/static/chunks/acf223168ac429f7.js","async":true}]],["$","html",null,{"lang":"en","children":["$","body",null,{"className":"antialiased overflow-hidden","children":["$","$L2",null,{"delayDuration":200,"children":["$","$L3",null,{"parallelRouterKey":"children","error":"$4","errorStyles":[],"errorScripts":[["$","script","script-0",{"src":"/_next/static/chunks/b112c2f519e4b429.js","async":true}]],"template":["$","$L5",null,{}],"notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]]}]}]}]}]]}],"loading":null,"isPartial":false}
|
package/out/__next._tree.txt
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
:HL["/_next/static/chunks/83ab8820627f8bfe.css","style"]
|
|
2
2
|
:HL["/_next/static/chunks/8a5bd6fe3abc8091.css","style"]
|
|
3
|
-
0:{"buildId":"
|
|
3
|
+
0:{"buildId":"4eCLtLp-IPL1tppPGnHZE","tree":{"name":"","paramType":null,"paramKey":"","hasRuntimePrefetch":false,"slots":{"children":{"name":"__PAGE__","paramType":null,"paramKey":"__PAGE__","hasRuntimePrefetch":false,"slots":null,"isRootLayout":false}},"isRootLayout":true},"staleTime":300}
|
|
@@ -33,7 +33,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${t.do
|
|
|
33
33
|
`),n.sourceMap&&(e+=`
|
|
34
34
|
🗺️ Source Map: ${Object.keys(n.sourceMap.mappings??{}).length} nodes mapped
|
|
35
35
|
`),e+=`
|
|
36
|
-
${n.code}`}return`❌ Compilation failed: ${n.error}`}catch(e){return`❌ Compilation request failed: ${e instanceof Error?e.message:String(e)}`}},[t]),handleValidate:r,handleAnalyze:o,handleExportIR:n,handleDownloadIR:(0,I.useCallback)(()=>{let e=t(),n=new Blob([JSON.stringify(e,null,2)],{type:"application/json"}),r=URL.createObjectURL(n),o=document.createElement("a");o.href=r,o.download=`${e.meta.name.replace(/\s+/g,"-").toLowerCase()||"flow"}.flow.json`,o.click(),URL.revokeObjectURL(r)},[t])}),k=function(){let e=iw(e=>e.loadIR),t=cc(),[n,r]=(0,I.useState)(""),[o,a]=(0,I.useState)(!1),[i,s]=(0,I.useState)(""),[l,d]=(0,I.useState)(0),c=(0,I.useRef)(null),u=(0,I.useCallback)(e=>{d(cm(e))},[]),p=(0,I.useCallback)(()=>{c.current?.abort()},[]),f=(0,I.useCallback)(async()=>{if(!n.trim())return"";a(!0),s(""),c.current=new AbortController;try{let r=t.getActiveConfig();if(r)return await cx(r,n.trim(),c,s,e);return await cv(n.trim(),c,e)}catch(e){if("AbortError"===e.name)return"⏹️ AI generation cancelled";return`❌ AI request failed: ${e instanceof Error?e.message:String(e)}`}finally{a(!1),s(""),c.current=null}},[n,t,e]);return{aiPrompt:n,setAiPrompt:r,aiLoading:o,aiStreamContent:i,tokenEstimate:l,handleAIGenerate:f,handleCancelAI:p,updateTokenEstimate:u}}(),_=function(t){let n=iw(e=>e.loadIR),[r,o]=(0,I.useState)(!1),[a,i]=(0,I.useState)([]),s=(0,I.useCallback)(()=>new Promise(e=>{let r=document.createElement("input");r.type="file",r.accept=".json,.flow.json",r.onchange=async r=>{let o=r.target.files?.[0];if(!o)return void e(null);let a=await o.text();try{let r=JSON.parse(a),o=(0,cp.validateFlowIR)(r);if(!o.valid){let n="❌ Loaded IR validation failed:\n"+o.errors.map(e=>` [${e.code}] ${e.message}`).join("\n");t(n),e(n);return}n(r);let i=`✅ Flow diagram loaded: "${r.meta?.name??"Untitled"}"`;t(i),e(i)}catch{let n="❌ JSON parse failed. Please verify the file format.";t(n),e(n)}},r.click()}),[n,t]),l=(0,I.useCallback)(()=>{let
|
|
36
|
+
${n.code}`}return`❌ Compilation failed: ${n.error}`}catch(e){return`❌ Compilation request failed: ${e instanceof Error?e.message:String(e)}`}},[t]),handleValidate:r,handleAnalyze:o,handleExportIR:n,handleDownloadIR:(0,I.useCallback)(()=>{let e=t(),n=new Blob([JSON.stringify(e,null,2)],{type:"application/json"}),r=URL.createObjectURL(n),o=document.createElement("a");o.href=r,o.download=`${e.meta.name.replace(/\s+/g,"-").toLowerCase()||"flow"}.flow.json`,o.click(),setTimeout(()=>URL.revokeObjectURL(r),1e4)},[t])}),k=function(){let e=iw(e=>e.loadIR),t=cc(),[n,r]=(0,I.useState)(""),[o,a]=(0,I.useState)(!1),[i,s]=(0,I.useState)(""),[l,d]=(0,I.useState)(0),c=(0,I.useRef)(null),u=(0,I.useCallback)(e=>{d(cm(e))},[]),p=(0,I.useCallback)(()=>{c.current?.abort()},[]),f=(0,I.useCallback)(async()=>{if(!n.trim())return"";a(!0),s(""),c.current=new AbortController;try{let r=t.getActiveConfig();if(r)return await cx(r,n.trim(),c,s,e);return await cv(n.trim(),c,e)}catch(e){if("AbortError"===e.name)return"⏹️ AI generation cancelled";return`❌ AI request failed: ${e instanceof Error?e.message:String(e)}`}finally{a(!1),s(""),c.current=null}},[n,t,e]);return{aiPrompt:n,setAiPrompt:r,aiLoading:o,aiStreamContent:i,tokenEstimate:l,handleAIGenerate:f,handleCancelAI:p,updateTokenEstimate:u}}(),_=function(t){let n=iw(e=>e.loadIR),[r,o]=(0,I.useState)(!1),[a,i]=(0,I.useState)([]),s=(0,I.useCallback)(()=>new Promise(e=>{let r=document.createElement("input");r.type="file",r.accept=".json,.flow.json",r.onchange=async r=>{let o=r.target.files?.[0];if(!o)return void e(null);let a=await o.text();try{let r=JSON.parse(a),o=(0,cp.validateFlowIR)(r);if(!o.valid){let n="❌ Loaded IR validation failed:\n"+o.errors.map(e=>` [${e.code}] ${e.message}`).join("\n");t(n),e(n);return}n(r);let i=`✅ Flow diagram loaded: "${r.meta?.name??"Untitled"}"`;t(i),e(i)}catch{let n="❌ JSON parse failed. Please verify the file format.";t(n),e(n)}},r.click()}),[n,t]),l=(0,I.useCallback)(()=>{let n=document.createElement("input");n.type="file",n.accept=".json,.yaml,.yml",n.onchange=async n=>{let r=n.target.files?.[0];if(!r)return;let a=await r.text();try{let n;if(r.name.match(/\.ya?ml$/i)){let{parse:t}=await e.A(9830);n=t(a)}else n=JSON.parse(a);let s=await fetch(`${(0,cf.getApiBase)()}/api/import-openapi`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({spec:n})}),l=await s.json();l.flows&&l.flows.length>0?(i(l.flows),o(!0)):t(`❌ OpenAPI import failed: ${l.errors?.join(", ")??"No endpoints found"}`)}catch{t("❌ Parse failed. Please verify the file is a valid OpenAPI 3.x JSON or YAML file.")}},n.click()},[t]),d=(0,I.useCallback)(e=>{n(e),o(!1);let r=`✅ Endpoint loaded: "${e.meta?.name??"Untitled"}"
|
|
37
37
|
Total ${e.nodes?.length??0} nodes`;return t(r),r},[n,t]);return{showOpenAPIDialog:r,setShowOpenAPIDialog:o,openAPIFlows:a,handleLoadIRFromJSON:s,handleImportOpenAPI:l,handleSelectOpenAPIFlow:d,handleDecompileTS:(0,I.useCallback)(()=>{let r=document.createElement("input");r.type="file",r.accept=".ts,.tsx,.js,.jsx,.txt",r.onchange=async r=>{let o=r.target.files?.[0];if(!o)return;let a=await o.text();if(0===a.trim().length)return void t("❌ File is empty.");try{let{getApiBase:r}=await e.A(98984),i=await fetch(`${r()}/api/decompile`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({code:a,fileName:o.name.endsWith(".txt")?o.name.replace(/\.txt$/,".ts"):o.name})}),s=await i.json();if(s.success&&s.ir){n(s.ir);let e=Math.round((s.confidence??0)*100),r=`✅ TypeScript → IR decompilation successful
|
|
38
38
|
`;r+=`📊 Confidence score: ${e}%
|
|
39
39
|
📁 ${o.name}
|