feat(cli): wmill dev works with flows

This commit is contained in:
Ruben Fiszel
2025-02-13 01:25:11 +01:00
parent 8f1791a8c7
commit 9fd8fbd7b9
+58 -22
View File
@@ -8,8 +8,9 @@ import {
log,
open,
WebSocket,
yamlParseFile,
} from "./deps.ts";
import { GlobalOptions } from "./types.ts";
import { getTypeStrFromPath, GlobalOptions } from "./types.ts";
import { ignoreF } from "./sync.ts";
import { requireLogin, resolveWorkspace } from "./context.ts";
import {
@@ -19,6 +20,8 @@ import {
} from "./conf.ts";
import { exts } from "./script.ts";
import { inferContentTypeFromFilePath } from "./script_common.ts";
import { OpenFlow } from "./gen/types.gen.ts";
import { FlowFile, replaceInlineScripts } from "./flow.ts";
const PORT = 3001;
async function dev(opts: GlobalOptions & SyncOptions) {
@@ -27,54 +30,87 @@ async function dev(opts: GlobalOptions & SyncOptions) {
log.info("Started dev mode");
const conf = await readConfigFile();
let currentLastEdit: LastEdit | undefined = undefined;
let currentLastEdit: LastEditScript | LastEditFlow | undefined = undefined;
const watcher = Deno.watchFs(".");
const base = await Deno.realPath(".");
opts = await mergeConfigWithConfigFile(opts);
const ignore = await ignoreF(opts);
const changesTimeouts: Record<string, number> = {};
async function watchChanges() {
for await (const event of watcher) {
log.debug(">>>> event", event);
// Example event: { kind: "create", paths: [ "/home/alice/deno/foo.txt" ] }
await loadPaths(event.paths);
// console.log(">>>> event", event);
const key = event.paths.join(",");
if (changesTimeouts[key]) {
clearTimeout(changesTimeouts[key]);
}
changesTimeouts[key] = setTimeout(async () => {
delete changesTimeouts[key];
await loadPaths(event.paths);
}, 100);
}
}
const DOT_FLOW_SEP = ".flow" + SEP;
async function loadPaths(pathsToLoad: string[]) {
const paths = pathsToLoad.filter((path) =>
exts.some((ext) => path.endsWith(ext))
const paths = pathsToLoad.filter(
(path) =>
exts.some((ext) => path.endsWith(ext)) || path.includes(DOT_FLOW_SEP)
);
if (paths.length == 0) {
return;
}
const cpath = (await Deno.realPath(paths[0])).replace(base + SEP, "");
console.log("Detected change in " + cpath);
if (!ignore(cpath, false)) {
const content = await Deno.readTextFile(cpath);
const splitted = cpath.split(".");
const wmPath = splitted[0];
const lang = inferContentTypeFromFilePath(cpath, conf.defaultTs);
currentLastEdit = {
content,
path: wmPath,
language: lang,
};
broadcastChanges(currentLastEdit);
log.info("Updated " + wmPath);
const typ = getTypeStrFromPath(cpath);
log.info("Detected change in " + cpath + " (" + typ + ")");
if (typ == "flow") {
const localPath = cpath.split(DOT_FLOW_SEP)[0] + DOT_FLOW_SEP;
const localFlow = (await yamlParseFile(
localPath + "flow.yaml"
)) as FlowFile;
replaceInlineScripts(localFlow.value.modules, localPath, undefined);
currentLastEdit = {
type: "flow",
flow: localFlow,
uriPath: localPath,
};
log.info("Updated " + localPath);
broadcastChanges(currentLastEdit);
} else if (typ == "script") {
const content = await Deno.readTextFile(cpath);
const splitted = cpath.split(".");
const wmPath = splitted[0];
const lang = inferContentTypeFromFilePath(cpath, conf.defaultTs);
currentLastEdit = {
type: "script",
content,
path: wmPath,
language: lang,
};
log.info("Updated " + wmPath);
broadcastChanges(currentLastEdit);
}
}
}
type LastEdit = {
type LastEditScript = {
type: "script";
content: string;
path: string;
language: string;
};
type LastEditFlow = {
type: "flow";
flow: OpenFlow;
uriPath: string;
};
const connectedClients: Set<WebSocket> = new Set();
// Function to send a message to all connected clients
function broadcastChanges(lastEdit: LastEdit) {
function broadcastChanges(lastEdit: LastEditScript | LastEditFlow) {
for (const client of connectedClients.values()) {
client.send(JSON.stringify(lastEdit));
}
@@ -119,7 +155,7 @@ async function dev(opts: GlobalOptions & SyncOptions) {
// Start the server
const port = await getPort.default({ port: 3001 });
const url =
`${workspace.remote}scripts/dev?workspace=${workspace.workspaceId}&local=true` +
`${workspace.remote}dev?workspace=${workspace.workspaceId}&local=true&wm_token=${workspace.token}` +
(port === PORT ? "" : `&port=${port}`);
console.log(`Go to ${url}`);