Today I'm shipping v19.3.0. The headline is strict Content-Security-Policy support: component styles are no longer emulated, so a style-src built from hashes works without 'unsafe-inline' — including on static hosting. And this release came from the community, from the first reports to the shipped code.
The release adds:
style-src can allow.<f-snap-connection> emits fSnapTargetChange, so both endpoints can be styled while the snap preview is visible.fitToScreen with a scale cap - fitting a small graph no longer magnifies it to fill the viewport.FF1010 and FF1011 turn silent app-side misconfigurations into one-shot dev warnings.There are no breaking changes in this release.
Angular injects component styles at runtime as <style> elements. Under a strict Content-Security-Policy, every one of them must be allowed by style-src — and under emulated encapsulation that was practically impossible to do with hashes, because every rule is rewritten with generated scoping attributes:
Those attributes are an artifact of the build. Hash the style text today, and a refactor that changes component registration order can change it tomorrow — failing in production as silently unstyled components. Nonces avoid that, but need a server rendering HTML per response, which rules out static hosting.
v19.3 removes the blocker (#329): all 14 styled components declare ViewEncapsulation.None, and every rule is written against the component's own element selector — f-selection-area { … } instead of :host { … }. The emitted CSS is byte-for-byte what's in the source. Hash it once:
We verified it the way an integrator would deploy it: a production build of this documentation site behind a real, enforced header. With a deliberately wrong hash the canvas visibly degrades — proof the policy is enforced. With the collected hashes, everything renders and a full drag-to-connect gesture works. Zero violations, zero 'unsafe-inline'.
One scoping subtlety was caught in review: emulated encapsulation used to limit rules like :host svg to the component's own template, while an unscoped f-connection svg would also reach projected user content — custom svg[fMarker] markers and icons inside [fConnectionContent]. The shipped rules use the child combinator (f-connection > svg), which reproduces the old scoping exactly, and a regression spec pins that contract.
Connection routing through waypoints is reworked (#324). Before, a waypoint was treated too much like a connector: the router added connector-style stubs and extra bends around it, some paths missed a dragged waypoint entirely, and handles on rounded corners sat on the sharp corner point — visibly off the rendered line.
Now a waypoint is a pass-through anchor:
Two interaction fixes, both reported with StackBlitz reproductions:
fConnectOnNode) used to attach to the node's first registered connector. It now attaches to the connector closest to the drop point (#326).Both sound small in a changelog, but they are exactly the kind of behavior users feel as "the editor does what I meant".
<f-snap-connection> now emits fSnapTargetChange while a connection is being created (#180):
The event carries { sourceId, targetId }: one event when a connector enters the snap threshold or the snap switches to another connector, and one with targetId: undefined when the snap is released or the gesture ends. One event per change — not one per pointer move — so it is safe to drive endpoint styling from it directly.
fitToScreen accepts an optional maxScale argument (#147):
With maxScale: 1 a graph smaller than the viewport is centered at its natural size instead of being blown up to fill it. Larger graphs scale down to fit as before.
Two new dev-mode warnings joined the FFxxxx family — one-shot per cause, stripped from production builds, both born from real support issues:
::before/::after while the connector element itself is 0×0. Hit-testing uses the element's box, so drops land past the connector (#326).fNodePosition stayed put, so model-driven features — the minimap, fitToScreen, auto-layout — disagree with what the canvas shows (#331).Both thresholds are configurable, 0 switches a check off:
The full code list lives in the errors and warnings guide.
Heavy connection redraws can run in a web worker. The worker state is provided per f-flow instance, but its dispose() had no caller: destroy a flow, and its worker thread and blob URL stayed alive (#330).
For a single long-lived editor that is invisible. For an application that opens and closes editors — a dialog with a flow inside, a tab switcher, a router that recreates the page — it is a slow leak of threads.
Disposal is now wired into the flow's own teardown: ngOnDestroy terminates the worker, revokes its blob URL, and rejects in-flight requests. Each flow cleans up exactly what it created.
ng add @foblex/flow now also writes a canonical Foblex Flow instruction block to AGENTS.md and makes sure Claude Code loads it through an @AGENTS.md import in CLAUDE.md — idempotently, preserving whatever project instructions already exist.
Together with the version-matched AI.md shipped inside the npm package and the LLM-readable docs at flow.foblex.com/llms.txt, the goal is simple: an AI coding agent working in your repository should know how the library actually works — the same diagnostics, the same verification workflow, the same rules a human reads.
This release belongs to the community:
fitToScreen scale cap.FF1011.For me, this is the shape of open source I care about: people who use the library in real editors, care enough to make it better, and shape where it goes next.
svg[fMarker] markers, [fConnectionContent] — is not affected by library svg rules.ERESOLVE on the layout packages: @foblex/flow-dagre-layout and @foblex/flow-elk-layout now declare the correct 19.x peer range.style-src 'self' 'sha256-…'. No nonce infrastructure required.This release has no single big feature, and that is the point: waypoints route like you drew them, drops land where you aimed, misconfigurations report themselves, and the library no longer stands between your application and a strict CSP. It is also the most community-driven release the project has had — which says more about where the project is than any feature could.
If you're building a visual editor in Angular and want a native Angular solution (not a React wrapper) — take a look.
And if you like what I'm building, please consider starring the repo ⭐
It helps the project a lot.