{"_id":"@mr_mint/elkjs-libavoid","_rev":"7-d64be7b6e74ddb3a4eba03e4b7a95f80","name":"@mr_mint/elkjs-libavoid","dist-tags":{"next":"0.1.0","latest":"0.5.0"},"versions":{"0.0.0":{"name":"@mr_mint/elkjs-libavoid","version":"0.0.0","keywords":["elk","elkjs","libavoid","graph","layout","edge-routing","connector-routing","obstacle-avoiding"],"license":"MIT","_id":"@mr_mint/elkjs-libavoid@0.0.0","maintainers":[{"name":"mr_mint","email":"mr.mint89@gmail.com"}],"homepage":"https://github.com/mrmint/elkjs-libavoid#readme","bugs":{"url":"https://github.com/mrmint/elkjs-libavoid/issues"},"dist":{"shasum":"9cebd79aefe6b808f0cf80d6d152cb6777fb5c5b","tarball":"https://registry.npmjs.org/@mr_mint/elkjs-libavoid/-/elkjs-libavoid-0.0.0.tgz","fileCount":12,"integrity":"sha512-aP1HYQa2vUvc6aIpn2GYfmnyzV3A95lG3+HhI2lUKNDFq70N7PHT38G7WdVwugYDDbr/ZzdPtGmNIxw6Sb1hdw==","signatures":[{"sig":"MEUCIQCnfxr0AA+1/jST1806PpJzHscM7+p66TdaYRaIh8BgYwIgQYMulh57pSUaZi4spCH55ZcUfGfbrTW0QNUuuVO5Gs4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":504633},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.mjs","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.cjs"}},"gitHead":"36d70e820de5d481058a6c14eaa2266a70df4175","scripts":{"dev":"tsdown --watch","lint":"biome ci && tsc --noEmit","test":"vitest run","build":"tsdown","check":"biome check","format":"biome format --write","release":"changeset publish","version":"changeset version","changeset":"changeset","check:fix":"biome check --write","postbuild":"cp node_modules/libavoid-js/dist/libavoid.wasm dist/","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"mr_mint","email":"mr.mint89@gmail.com"},"repository":{"url":"git+https://github.com/mrmint/elkjs-libavoid.git","type":"git"},"_npmVersion":"11.11.0","description":"Obstacle-avoiding edge routing for ELK JSON graphs using libavoid","directories":{},"_nodeVersion":"25.8.0","dependencies":{"libavoid-js":"^0.5.0-beta.5"},"_hasShrinkwrap":false,"devDependencies":{"elkjs":"^0.9.3","tsdown":"^0.21.1","vitest":"^4.0.18","typescript":"^5.8.2","@biomejs/biome":"2.4.6","@changesets/cli":"^2.29.0"},"peerDependencies":{"elkjs":">=0.8.0"},"peerDependenciesMeta":{"elkjs":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/elkjs-libavoid_0.0.0_1773075969342_0.27597320554107774","host":"s3://npm-registry-packages-npm-production"}},"0.1.0":{"name":"@mr_mint/elkjs-libavoid","version":"0.1.0","keywords":["elk","elkjs","libavoid","graph","layout","edge-routing","connector-routing","obstacle-avoiding"],"license":"MIT","_id":"@mr_mint/elkjs-libavoid@0.1.0","maintainers":[{"name":"mr_mint","email":"mr.mint89@gmail.com"}],"homepage":"https://github.com/MrMint/elkjs-libavoid#readme","bugs":{"url":"https://github.com/MrMint/elkjs-libavoid/issues"},"dist":{"shasum":"66d518cf0a0a16440b7c1f87c64b2bde8a591602","tarball":"https://registry.npmjs.org/@mr_mint/elkjs-libavoid/-/elkjs-libavoid-0.1.0.tgz","fileCount":12,"integrity":"sha512-aBYSFrhaFO1uY8xp+vsVgaMKOhm/e3vnDaHEB10S5X/NMmolqt3GsC4PAwWQeGWSDyHC54/1mCCxBrF6EDt6jQ==","signatures":[{"sig":"MEQCH0YLlx+Ou4qGe/IPYmk2RVH32svzQWgAEk6/kWwxz2ICIQCNTLMnJvMmng4sutiZ409z43Wj3T8FPKylJc277CFyLA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@mr_mint%2felkjs-libavoid@0.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":595880},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.mts","module":"./dist/index.mjs","engines":{"node":">=20"},"exports":{".":{"import":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"gitHead":"1a0b236d0e0a3984b6920a17eb837dc9d3d84f43","scripts":{"dev":"tsdown --watch","lint":"biome ci && tsc --noEmit","test":"vitest run","build":"tsdown","check":"biome check","format":"biome format --write","release":"changeset publish","version":"changeset version","changeset":"changeset","check:fix":"biome check --write","postbuild":"cp node_modules/libavoid-js/dist/libavoid.wasm dist/","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:fb3bb5aa-dd17-4e0d-9e33-db6cdd1f6178"}},"repository":{"url":"git+https://github.com/MrMint/elkjs-libavoid.git","type":"git"},"_npmVersion":"11.9.0","description":"Obstacle-avoiding edge routing for ELK JSON graphs using libavoid","directories":{},"_nodeVersion":"24.14.0","dependencies":{"libavoid-js":"0.5.0-beta.5"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"elkjs":"0.11.1","tsdown":"0.21.1","vitest":"4.0.18","typescript":"5.9.3","@biomejs/biome":"2.4.6","@changesets/cli":"2.30.0"},"peerDependencies":{"elkjs":">=0.8.0"},"peerDependenciesMeta":{"elkjs":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/elkjs-libavoid_0.1.0_1773080802642_0.07339742237956881","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@mr_mint/elkjs-libavoid","version":"0.2.0","keywords":["elk","elkjs","libavoid","graph","layout","edge-routing","connector-routing","obstacle-avoiding"],"license":"MIT","_id":"@mr_mint/elkjs-libavoid@0.2.0","maintainers":[{"name":"mr_mint","email":"mr.mint89@gmail.com"}],"homepage":"https://github.com/MrMint/elkjs-libavoid#readme","bugs":{"url":"https://github.com/MrMint/elkjs-libavoid/issues"},"dist":{"shasum":"ba3d51df39697e6a5e4563ed9153c2dcb2e10a4a","tarball":"https://registry.npmjs.org/@mr_mint/elkjs-libavoid/-/elkjs-libavoid-0.2.0.tgz","fileCount":12,"integrity":"sha512-dolJQHtsLYGksogQnY3pe8LV0UuVhQiYjYzpwxBJPzJfaF+afUfQJjaY5743dAAh79qc1mwOnvxJXGHESAXsDw==","signatures":[{"sig":"MEUCIFqz4Qez79l9wQylbsrk0qWAAMJnD/30SQc0MdaJNUdzAiEAsAjIUTA8tlsr41jM9nzYtB+eDWbHCawt7h3B4SoxE3Y=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@mr_mint%2felkjs-libavoid@0.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":687212},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.mts","module":"./dist/index.mjs","engines":{"node":">=20"},"exports":{".":{"import":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"gitHead":"8fe7b729222e3faa0bf4766eccd3e3a9e7d008b1","scripts":{"dev":"tsdown --watch","lint":"biome ci && tsc --noEmit","test":"vitest run","build":"tsdown","check":"biome check","format":"biome format --write","release":"changeset publish","version":"changeset version","changeset":"changeset","check:fix":"biome check --write","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:fb3bb5aa-dd17-4e0d-9e33-db6cdd1f6178"}},"repository":{"url":"git+https://github.com/MrMint/elkjs-libavoid.git","type":"git"},"_npmVersion":"11.9.0","description":"Obstacle-avoiding edge routing for ELK JSON graphs using libavoid","directories":{},"_nodeVersion":"24.14.0","dependencies":{"libavoid-js":"0.5.0-beta.5"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"elkjs":"0.11.1","tsdown":"0.21.1","vitest":"4.0.18","typescript":"5.9.3","@types/node":"^25.4.0","@biomejs/biome":"2.4.6","@changesets/cli":"2.30.0"},"peerDependencies":{"elkjs":">=0.8.0"},"peerDependenciesMeta":{"elkjs":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/elkjs-libavoid_0.2.0_1773086247401_0.24811073934872563","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@mr_mint/elkjs-libavoid","version":"0.3.0","keywords":["elk","elkjs","libavoid","graph","layout","edge-routing","connector-routing","obstacle-avoiding"],"license":"MIT","_id":"@mr_mint/elkjs-libavoid@0.3.0","maintainers":[{"name":"mr_mint","email":"mr.mint89@gmail.com"}],"homepage":"https://github.com/MrMint/elkjs-libavoid#readme","bugs":{"url":"https://github.com/MrMint/elkjs-libavoid/issues"},"dist":{"shasum":"edab3fe2e66808e0462f1dcc4ff2344a3a0d0c66","tarball":"https://registry.npmjs.org/@mr_mint/elkjs-libavoid/-/elkjs-libavoid-0.3.0.tgz","fileCount":20,"integrity":"sha512-Ihctf5m8hgDcHb3bECFY+oJA5hW/Yl9F/cGHCV0ONqzHwRBIMzI369KCA0u+UF+64ZWZSE14orLmL95fxwUHEw==","signatures":[{"sig":"MEUCIQD0CoyTxsDpYi3exr34ZCpQ6oX2IxG0Ys7GCLc+rtoArwIgE89ezfMqBHzGzv7nyFGliw9WZI2CdempBL2MS2gnbSY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@mr_mint%2felkjs-libavoid@0.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":676807},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.mts","module":"./dist/index.mjs","engines":{"node":">=20"},"exports":{".":{"import":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}},"./node":{"import":{"types":"./dist/node.d.mts","default":"./dist/node.mjs"},"require":{"types":"./dist/node.d.cts","default":"./dist/node.cjs"}}},"gitHead":"8d6797426f629aa86e99f6bee2a5c7f4bb877e71","scripts":{"dev":"tsdown --watch","lint":"biome ci && tsc --noEmit","test":"vitest run","build":"tsdown","check":"biome check","format":"biome format --write","release":"changeset publish","version":"changeset version","changeset":"changeset","check:fix":"biome check --write","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:fb3bb5aa-dd17-4e0d-9e33-db6cdd1f6178"}},"repository":{"url":"git+https://github.com/MrMint/elkjs-libavoid.git","type":"git"},"_npmVersion":"11.9.0","description":"Obstacle-avoiding edge routing for ELK JSON graphs using libavoid","directories":{},"_nodeVersion":"24.14.0","dependencies":{"libavoid-js":"0.5.0-beta.5"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"elkjs":"0.11.1","tsdown":"0.21.1","vitest":"4.0.18","typescript":"5.9.3","@types/node":"^25.4.0","@biomejs/biome":"2.4.6","@changesets/cli":"2.30.0"},"peerDependencies":{"elkjs":">=0.8.0"},"peerDependenciesMeta":{"elkjs":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/elkjs-libavoid_0.3.0_1773089477711_0.12480427367610192","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@mr_mint/elkjs-libavoid","version":"0.4.0","keywords":["elk","elkjs","libavoid","graph","layout","edge-routing","connector-routing","obstacle-avoiding"],"license":"MIT","_id":"@mr_mint/elkjs-libavoid@0.4.0","maintainers":[{"name":"mr_mint","email":"mr.mint89@gmail.com"}],"homepage":"https://github.com/MrMint/elkjs-libavoid#readme","bugs":{"url":"https://github.com/MrMint/elkjs-libavoid/issues"},"dist":{"shasum":"b3b3cbe8cf7c131494556bd818af3688bedc2bd3","tarball":"https://registry.npmjs.org/@mr_mint/elkjs-libavoid/-/elkjs-libavoid-0.4.0.tgz","fileCount":20,"integrity":"sha512-noo0jIPnlRGqO2SBMVc8XmQp1umEYPdvtI2BFQc+VqjkprDZDUjieFXD6cagG6mItSX+jM97mX9bn9QiDnW1cw==","signatures":[{"sig":"MEUCIHjGhAFWpApS8oWu28FQamhxqy1LfpV2TcuZ9dnFVw9+AiEAsvfQznKEf1o2IBD/2crBValMakxhqOY8c3aUAQe+DY0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@mr_mint%2felkjs-libavoid@0.4.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":682893},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.mts","module":"./dist/index.mjs","engines":{"node":">=20"},"exports":{".":{"import":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}},"./node":{"import":{"types":"./dist/node.d.mts","default":"./dist/node.mjs"},"require":{"types":"./dist/node.d.cts","default":"./dist/node.cjs"}}},"gitHead":"e601d3f5cbc9716606d121ab94dd32265b744e78","scripts":{"dev":"tsdown --watch","lint":"biome ci && tsc --noEmit","test":"vitest run","build":"tsdown","check":"biome check","format":"biome format --write","release":"changeset publish","version":"changeset version","changeset":"changeset","check:fix":"biome check --write","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:fb3bb5aa-dd17-4e0d-9e33-db6cdd1f6178"}},"repository":{"url":"git+https://github.com/MrMint/elkjs-libavoid.git","type":"git"},"_npmVersion":"11.9.0","description":"Obstacle-avoiding edge routing for ELK JSON graphs using libavoid","directories":{},"_nodeVersion":"24.14.0","dependencies":{"libavoid-js":"0.5.0-beta.5"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"elkjs":"0.11.1","tsdown":"0.21.1","vitest":"4.0.18","typescript":"5.9.3","@types/node":"^25.4.0","@biomejs/biome":"2.4.6","@changesets/cli":"2.30.0"},"peerDependencies":{"elkjs":">=0.8.0"},"peerDependenciesMeta":{"elkjs":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/elkjs-libavoid_0.4.0_1773091872356_0.9628307875397006","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"name":"@mr_mint/elkjs-libavoid","version":"0.5.0","description":"Obstacle-avoiding edge routing for ELK JSON graphs using libavoid","type":"module","sideEffects":false,"main":"./dist/index.cjs","module":"./dist/index.mjs","types":"./dist/index.d.mts","exports":{".":{"import":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}},"./node":{"import":{"types":"./dist/node.d.mts","default":"./dist/node.mjs"},"require":{"types":"./dist/node.d.cts","default":"./dist/node.cjs"}}},"scripts":{"build":"tsdown","changeset":"changeset","check":"biome check","check:fix":"biome check --write","dev":"tsdown --watch","format":"biome format --write","lint":"biome ci && tsc --noEmit","release":"changeset publish","test":"vitest run","test:coverage":"vitest run --coverage","test:watch":"vitest","typecheck":"tsc --noEmit","version":"changeset version"},"dependencies":{"libavoid-js":"0.5.0-beta.5"},"peerDependencies":{"elkjs":">=0.8.0"},"peerDependenciesMeta":{"elkjs":{"optional":true}},"devDependencies":{"@biomejs/biome":"2.4.6","@changesets/cli":"2.30.0","@types/node":"^25.4.0","elkjs":"0.11.1","tsdown":"0.21.1","typescript":"5.9.3","vitest":"4.0.18"},"keywords":["elk","elkjs","libavoid","graph","layout","edge-routing","connector-routing","obstacle-avoiding"],"license":"MIT","repository":{"type":"git","url":"git+https://github.com/MrMint/elkjs-libavoid.git"},"publishConfig":{"access":"public"},"engines":{"node":">=20"},"gitHead":"24b98cd4393eb55111ec21c35aba3df736f5b3f1","_id":"@mr_mint/elkjs-libavoid@0.5.0","bugs":{"url":"https://github.com/MrMint/elkjs-libavoid/issues"},"homepage":"https://github.com/MrMint/elkjs-libavoid#readme","_nodeVersion":"24.14.0","_npmVersion":"11.9.0","dist":{"integrity":"sha512-kFxLFRCNh8ph3wEg7ml0I0xGT4qSWHK6ytC4LPMa18bGiQru9cTmoskRlzjiJUJCAVDaRfXC1DzstQYpRRxbuQ==","shasum":"9fd9e4aa95568547d0d4e91f23c0357dabbfb698","tarball":"https://registry.npmjs.org/@mr_mint/elkjs-libavoid/-/elkjs-libavoid-0.5.0.tgz","fileCount":20,"unpackedSize":716765,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@mr_mint%2felkjs-libavoid@0.5.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQC/BMTGmDVdsm+HQ+Wk22oBTxs+Hkwp94kSkKHqUFIDWgIhALC/2Si5yNSSnqF+Qjy54kkb9+ye7gGPqhsMuLucE69R"}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:fb3bb5aa-dd17-4e0d-9e33-db6cdd1f6178"}},"directories":{},"maintainers":[{"name":"mr_mint","email":"mr.mint89@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/elkjs-libavoid_0.5.0_1773174384194_0.9873989800292922"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-09T17:06:09.238Z","modified":"2026-03-10T20:26:24.746Z","0.0.0":"2026-03-09T17:06:09.518Z","0.1.0":"2026-03-09T18:26:42.908Z","0.2.0":"2026-03-09T19:57:27.558Z","0.3.0":"2026-03-09T20:51:17.858Z","0.4.0":"2026-03-09T21:31:12.537Z","0.5.0":"2026-03-10T20:26:24.419Z"},"bugs":{"url":"https://github.com/MrMint/elkjs-libavoid/issues"},"license":"MIT","homepage":"https://github.com/MrMint/elkjs-libavoid#readme","keywords":["elk","elkjs","libavoid","graph","layout","edge-routing","connector-routing","obstacle-avoiding"],"repository":{"type":"git","url":"git+https://github.com/MrMint/elkjs-libavoid.git"},"description":"Obstacle-avoiding edge routing for ELK JSON graphs using libavoid","maintainers":[{"name":"mr_mint","email":"mr.mint89@gmail.com"}],"readme":"# elkjs-libavoid\n\n[![CI](https://github.com/mrmint/elkjs-libavoid/actions/workflows/ci.yml/badge.svg)](https://github.com/mrmint/elkjs-libavoid/actions/workflows/ci.yml)\n[![npm](https://img.shields.io/npm/v/@mr_mint/elkjs-libavoid)](https://www.npmjs.com/package/@mr_mint/elkjs-libavoid)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\nObstacle-avoiding edge routing for ELK JSON graphs using [libavoid](https://github.com/mjwybrow/adaptagrams/tree/master/libavoid).\n\nUse [ELK.js](https://github.com/kieler/elkjs) (or any other tool) to position your nodes, then pass the graph to elkjs-libavoid to compute edge routes that avoid overlapping with nodes.\n\n## Installation\n\n```bash\nnpm install @mr_mint/elkjs-libavoid\n```\n\nelkjs is an optional peer dependency — install it if you need ELK for node layout:\n\n```bash\nnpm install elkjs\n```\n\n## Quick Start\n\n```ts\nimport ELK from \"elkjs\";\nimport { routeEdgesInPlace } from \"@mr_mint/elkjs-libavoid\";\n\nconst elk = new ELK();\n\n// 1. Define your graph\nconst graph = {\n  id: \"root\",\n  children: [\n    { id: \"n1\", width: 100, height: 50 },\n    { id: \"n2\", width: 100, height: 50 },\n    { id: \"n3\", width: 100, height: 50 },\n  ],\n  edges: [\n    { id: \"e1\", source: \"n1\", target: \"n2\" },\n    { id: \"e2\", source: \"n1\", target: \"n3\" },\n  ],\n};\n\n// 2. Layout nodes with ELK\nconst positioned = await elk.layout(graph);\n\n// 3. Route edges with libavoid (mutates graph in place)\nconst routed = await routeEdgesInPlace(positioned);\n// Edges now have sourcePoint, targetPoint, and bendPoints\n```\n\nOr use `routeEdges` to get route results without mutating the graph:\n\n```ts\nimport { routeEdges } from \"@mr_mint/elkjs-libavoid\";\n\nconst routes = await routeEdges(positioned);\n// routes is a Map<string, RouteResult> with absolute coordinates\nfor (const [edgeId, route] of routes) {\n  console.log(edgeId, route.sourcePoint, route.targetPoint, route.bendPoints);\n}\n```\n\n## API\n\n### `init(wasmPath?: string): Promise<void>`\n\nPre-initialize the libavoid WASM module. This is optional — `routeEdges`, `routeEdgesInPlace`, and `createRoutingSession` will call it automatically on first use in Node.js. Call it explicitly if you want to control when the WASM module loads.\n\n**Browser environments:** You **must** call `init()` with a URL to the `libavoid.wasm` file before using the routing APIs. Copy `libavoid.wasm` from `node_modules/libavoid-js/dist/` to your public directory.\n\n```ts\nimport { init } from \"@mr_mint/elkjs-libavoid\";\n\n// Node.js — auto-detected, no path needed:\nawait init();\n\n// Browser — must provide the WASM URL:\nawait init(\"/path/to/libavoid.wasm\");\n```\n\n### `routeEdges(graph, options?): Promise<Map<string, RouteResult>>`\n\nCompute obstacle-avoiding routes for all edges in an ELK JSON graph. Nodes must already have `x`, `y`, `width`, and `height` set. The input graph is **not** modified.\n\nReturns a `Map` of edge ID to `RouteResult`. Coordinates are **absolute** (not relative to parent nodes).\n\nSupports both ELK simple edge format (`source`/`target`) and extended format (`sources`/`targets`/`sections`), as well as ports and hierarchical (compound) graphs.\n\n```ts\nimport { routeEdges } from \"@mr_mint/elkjs-libavoid\";\n\nconst routes = await routeEdges(graph, {\n  routingType: \"orthogonal\",\n  shapeBufferDistance: 8,\n});\n\nfor (const [edgeId, route] of routes) {\n  // route.sourcePoint, route.targetPoint, route.bendPoints — absolute coords\n  // route.sourceSide, route.targetSide — \"north\" | \"south\" | \"east\" | \"west\"\n}\n```\n\n### `routeEdgesInPlace(graph, options?): Promise<ElkGraph>`\n\nCompute obstacle-avoiding routes and write them directly into the graph's edge objects. The graph is modified **in place** and also returned.\n\nCoordinates are written **relative** to the edge's owner node's content area (inside padding), matching the ELK JSON convention.\n\n```ts\nimport { routeEdgesInPlace } from \"@mr_mint/elkjs-libavoid\";\n\nconst routed = await routeEdgesInPlace(graph, {\n  routingType: \"orthogonal\",\n  shapeBufferDistance: 8,\n});\n// routed === graph, edges now have sourcePoint/targetPoint/bendPoints\n```\n\n### `createRoutingSession(graph, options?): Promise<RoutingSession>`\n\nCreate a long-lived routing session for incremental updates. Use this instead of `routeEdges()` when you need to update node positions frequently (e.g., during drag operations) without re-creating the entire router on every frame.\n\n```ts\nimport { createRoutingSession } from \"@mr_mint/elkjs-libavoid\";\n\nconst session = await createRoutingSession(graph, {\n  routingType: \"orthogonal\",\n});\n\n// On node drag:\nsession.moveNode(\"n1\", { x: newX, y: newY });\nconst routes = session.processTransaction();\n// routes is a Map<string, RouteResult> with absolute coordinates\n\n// Add/remove edges dynamically:\nsession.addEdge({ id: \"e3\", source: \"n1\", target: \"n3\" });\nsession.removeEdge(\"e1\");\nconst updatedRoutes = session.processTransaction();\n\n// Cleanup:\nsession.destroy();\n```\n\n`RoutingSession` implements `Symbol.dispose` for TC39 Explicit Resource Management:\n\n```ts\nusing session = await createRoutingSession(graph);\n```\n\n### `getWasmPath(): string`\n\nNode.js helper that returns the absolute path to the bundled `libavoid.wasm` file. Available from the `./node` subpath export.\n\n```ts\nimport { getWasmPath } from \"@mr_mint/elkjs-libavoid/node\";\n\nconst wasmPath = getWasmPath();\n```\n\n## Types\n\n### `RouteResult`\n\nReturned by `routeEdges()` and `RoutingSession.processTransaction()`.\n\n```ts\ninterface RouteResult {\n  sourcePoint: ElkPoint;\n  targetPoint: ElkPoint;\n  bendPoints: ElkPoint[];\n  sourceSide: ConnectionSide;\n  targetSide: ConnectionSide;\n}\n```\n\n### `ConnectionSide`\n\n```ts\ntype ConnectionSide = \"north\" | \"south\" | \"east\" | \"west\";\n```\n\n### `SelfLoopHandling`\n\n```ts\ntype SelfLoopHandling = \"skip\" | \"fallback\";\n```\n\n## Options\n\nAll options are optional. Pass them as the second argument to `routeEdges` or `routeEdgesInPlace`.\n\n### Router Options\n\nThese options are shared by `routeEdges`, `routeEdgesInPlace`, and `createRoutingSession`.\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `routingType` | `\"orthogonal\" \\| \"polyline\"` | `\"orthogonal\"` | Routing style — right-angle bends or diagonal segments |\n| `segmentPenalty` | `number` | `10` | Cost per segment beyond the first |\n| `anglePenalty` | `number` | `0` | Cost for tight bends |\n| `crossingPenalty` | `number` | `0` | Cost for edge crossings |\n| `clusterCrossingPenalty` | `number` | `0` | Cost for crossing cluster boundaries |\n| `fixedSharedPathPenalty` | `number` | `0` | Cost for sharing a path with an immovable edge |\n| `reverseDirectionPenalty` | `number` | `0` | Cost for routing backwards |\n| `portDirectionPenalty` | `number` | `100` | Cost for leaving a port in the wrong direction |\n| `shapeBufferDistance` | `number` | `4` | Padding around obstacles (in pixels) |\n| `idealNudgingDistance` | `number` | `4` | Spacing between parallel edge segments |\n| `nudgeOrthogonalSegmentsConnectedToShapes` | `boolean` | — | Nudge segments connected to shapes |\n| `nudgeOrthogonalTouchingColinearSegments` | `boolean` | — | Nudge touching colinear segments |\n| `performUnifyingNudgingPreprocessingStep` | `boolean` | — | Preprocessing step for unified nudging |\n| `nudgeSharedPathsWithCommonEndPoint` | `boolean` | — | Nudge shared paths that share an endpoint |\n\n### Routing Options\n\nThese additional options are available for `routeEdges` and `routeEdgesInPlace` only (not `createRoutingSession`).\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `edgeIds` | `string[]` | — | Only route edges with these IDs; others are left unchanged |\n| `selfLoopHandling` | `\"skip\" \\| \"fallback\"` | `\"skip\"` | How to handle self-loop edges (source === target). `\"skip\"` omits them; `\"fallback\"` generates a synthetic route |\n\n## Graph Format\n\nelkjs-libavoid works with the [ELK JSON format](https://eclipse.dev/elk/documentation/tooldevelopers/graphdatastructure/jsonformat.html). Nodes must be positioned before routing.\n\n### Simple Edges\n\n```ts\n{\n  id: \"root\",\n  children: [\n    { id: \"n1\", x: 0, y: 0, width: 100, height: 50 },\n    { id: \"n2\", x: 200, y: 100, width: 100, height: 50 },\n  ],\n  edges: [\n    { id: \"e1\", source: \"n1\", target: \"n2\" },\n  ],\n}\n```\n\nWith `routeEdgesInPlace`, each edge gets `sourcePoint`, `targetPoint`, and `bendPoints`.\n\n### Extended Edges\n\n```ts\nedges: [\n  { id: \"e1\", sources: [\"n1\"], targets: [\"n2\"] },\n]\n```\n\nWith `routeEdgesInPlace`, extended edges get a `sections` array with `startPoint`, `endPoint`, and `bendPoints`.\n\n### Ports\n\n```ts\nchildren: [\n  {\n    id: \"n1\", x: 0, y: 0, width: 100, height: 50,\n    ports: [{ id: \"p1\", x: 100, y: 25, width: 5, height: 5 }],\n  },\n],\nedges: [\n  { id: \"e1\", source: \"n1\", sourcePort: \"p1\", target: \"n2\" },\n]\n```\n\n### Hierarchical Graphs\n\nEdges defined within compound nodes are routed correctly with coordinates relative to their parent.\n\n```ts\n{\n  id: \"root\",\n  children: [\n    {\n      id: \"group\", x: 0, y: 0, width: 400, height: 200,\n      children: [\n        { id: \"a\", x: 10, y: 10, width: 50, height: 50 },\n        { id: \"b\", x: 200, y: 100, width: 50, height: 50 },\n      ],\n      edges: [{ id: \"e1\", source: \"a\", target: \"b\" }],\n    },\n  ],\n}\n```\n\n## Requirements\n\n- Node.js >= 20\n- A runtime that supports WebAssembly\n\n## Contributing\n\nContributions are welcome! Please open an issue or submit a pull request.\n\n```bash\n# Install dependencies\nnpm install\n\n# Run tests\nnpm test\n\n# Run tests in watch mode\nnpm run test:watch\n\n# Build\nnpm run build\n\n# Lint and format\nnpm run check:fix\n\n# Type check\nnpm run typecheck\n```\n\n## License\n\n[MIT](LICENSE)\n","readmeFilename":"README.md"}