From c95d0ca8f55a44fae0fd2d1cdaab0178800ceffc Mon Sep 17 00:00:00 2001 From: stroblme Date: Sun, 23 Aug 2026 18:32:51 +0200 Subject: [PATCH] Publish, delete and module installs rebuild only what changed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Publishing or deleting a flow now splices that one flow into the running graph instead of reconnecting every node in the installation, saving a shared node's source rebuilds the flows using it, and installing modules rebuilds only the flows holding a node that would not load. Renaming stays on the full rebuild — it rewrites message references in every other flow's document — and so does startup, which has no graph to splice into. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01StpRc2C6au1WJ1EUU7fsfu --- NOTEPAD.md | 6 ++++++ backend/fluksio/api/routes/flows.py | 6 +++--- backend/fluksio/api/routes/modules.py | 8 +++++++- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/NOTEPAD.md b/NOTEPAD.md index e782cc2..0013195 100644 --- a/NOTEPAD.md +++ b/NOTEPAD.md @@ -10,6 +10,12 @@ Deferring because out of scope is fine, but don't mention deferring than. ## Open +### Dashboard UI rework (dedicated session) + +Rework the dashboard UI to make it more flexible in terms of the look and feel. +I consider following design options a) overall appearance: material look or liquid glass (einUI https://github.com/einui/einui) b) color palette + + ### To be sorted - FEAT/UI: we promise testing, but currently don't provide an UI for testing e.g. mock values or probing edge cases of a flow. This should be resolved (in a dedicated session); I'm thinking of a "Labs" page, which allows simulating an installation with all the flows (using their draft states) and which allows injecting values or mocking values based on events in the past diff --git a/backend/fluksio/api/routes/flows.py b/backend/fluksio/api/routes/flows.py index a4c61ed..4f7600e 100644 --- a/backend/fluksio/api/routes/flows.py +++ b/backend/fluksio/api/routes/flows.py @@ -425,7 +425,7 @@ async def publish_flow( detail={"message": str(exc), "current_version": exc.current}, ) _audit("published", name, user) - await controller.reload() + await controller.reload_flow(name) return _detail(controller, published) @@ -475,7 +475,7 @@ async def delete_flow( # Its files are gone; its values and queued work would otherwise linger. await run_in_threadpool(controller.forget_flow, name) await run_in_threadpool(_forget_runs, session, name) - await controller.reload() + await controller.reload_flow(name) return Message(message=f"Deleted flow '{name}'") @@ -556,7 +556,7 @@ async def save_node_source( controller.store.write_lib_source, ref, source.code ) if changed: - await controller.reload() + await controller.reload_lib_users(ref) else: await run_in_threadpool( controller.store.write_node_source, name, node_id, source.code, True diff --git a/backend/fluksio/api/routes/modules.py b/backend/fluksio/api/routes/modules.py index 81836e1..9cf4f69 100644 --- a/backend/fluksio/api/routes/modules.py +++ b/backend/fluksio/api/routes/modules.py @@ -44,6 +44,12 @@ async def apply_modules( A manifest that does not resolve changes nothing: the venv is left as it was and the stored manifest is only written once the install succeeded. + + Only the flows already holding a node that would not load are rebuilt, + because those are the ones an install is called to fix. A flow that this + install *breaks* — a package taken back out from under it — is still green + and fails at call time with the node author's own import error, until + something rebuilds it. """ ok, output = await run_in_threadpool(modules.sync, body.requirements) if not ok: @@ -65,5 +71,5 @@ async def apply_modules( # packages that were just installed — a node that could not import one is # the reason this was called, and it stays red until it is built again. pool.respawn_all() - await controller.reload() + await controller.reload_failed_flows() return ApplyResult(ok=True, output=output)