Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build-test-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jobs:
- name: Setup Deno
uses: denoland/setup-deno@v2
with:
deno-version: "2.3.6"
deno-version: "2.5.x"
- name: Run unit tests
run: uv run pytest -n auto

Expand Down
6 changes: 5 additions & 1 deletion src/capellambse_context_diagrams/_elkjs.py
Original file line number Diff line number Diff line change
Expand Up @@ -400,14 +400,18 @@ def _spawn_process_binary(self) -> None:
def _spawn_process_deno(self) -> None:
log.debug("Spawning elk.js helper process using deno")
deno_location = shutil.which("deno")
script_location = pathlib.Path(__file__).parent / "interop" / "elk.ts"
if deno_location is None:
raise RuntimeError("Deno is not installed")

interop_dir = pathlib.Path(__file__).parent / "interop"
script_location = interop_dir / "elk.ts"
config_location = interop_dir / "deno.json"

self._proc = subprocess.Popen(
[
deno_location,
"run",
f"--config={config_location}",
"--allow-read",
"--allow-net",
"--allow-env",
Expand Down
5 changes: 3 additions & 2 deletions src/capellambse_context_diagrams/interop/deno.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"tasks": {
"build": "deno compile --allow-read --allow-net --allow-env --no-check elk.ts"
"imports": {
"elkjs": "npm:elkjs@^0.11.0",
"sprotty": "npm:sprotty@^1.4.0"
}
}
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
SPDX-FileCopyrightText: 2025 Copyright DB InfraGO AG and the capellambse-context-diagrams contributors
SPDX-FileCopyrightText: Copyright DB InfraGO AG and the capellambse-context-diagrams contributors
SPDX-License-Identifier: Apache-2.0
66 changes: 62 additions & 4 deletions src/capellambse_context_diagrams/interop/elk.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,71 @@
// SPDX-FileCopyrightText: 2024 Copyright DB InfraGO AG and the capellambse-context-diagrams contributors
// SPDX-FileCopyrightText: Copyright DB InfraGO AG and the capellambse-context-diagrams contributors
// SPDX-License-Identifier: Apache-2.0

import { createInterface } from "node:readline";
import process from "node:process";
import ELK from "npm:elkjs@0.11.0";
import ELK from "npm:elkjs";
import { ElkGraphJsonToSprotty } from "./elkgraph-to-sprotty.ts";
await import("npm:elkjs/lib/elk-worker.min.js"); // initialize the ELK layout engine

// @ts-ignore Deno doesn't find this type for some reason
const elk = new ELK();
interface Message {
id?: string;
cmd?: string;
[key: string]: any;
}

interface MessageEvent {
data: Message;
}

/**
* FakeWorker implementation for ELK.js in Deno environment.
* Bridges ELK's worker-based architecture with synchronous execution.
*/
class FakeWorker {
onmessage: ((event: MessageEvent) => void) | null = null;

postMessage(msg: Message): void {
setTimeout(() => {
try {
const globalSelf = globalThis as any;

if (globalSelf.onmessage) {
const originalPostMessage = globalSelf.postMessage;

globalSelf.postMessage = (responseMsg: Message) => {
if (this.onmessage) {
this.onmessage({ data: responseMsg });
}
};

globalSelf.onmessage({ data: msg });
globalSelf.postMessage = originalPostMessage;
} else {
throw new Error(
"ELK worker not initialized: globalThis.onmessage is undefined"
);
}
} catch (err) {
if (this.onmessage) {
this.onmessage({
data: {
id: msg.id,
error: err instanceof Error ? err.message : String(err),
},
});
}
}
}, 0);
}

terminate(): void {
this.onmessage = null;
}
}

const elk = new ELK({
workerFactory: () => new FakeWorker(),
});

console.log("--- ELK layouter started ---");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import type {
SGraphSchema,
Point,
Dimension,
} from "npm:sprotty@^0.8.0";
} from "npm:sprotty";
import {
ElkShape,
ElkNode,
Expand Down