v19.3 is a community release: both changes in it were contributed by @chris-perry, from the problem statement to the pull request.
There are no breaking changes. The documented CSS classes and the shipped SCSS theme are untouched.
Styles a strict CSP can hash
Angular injects component styles at runtime as <style> elements. Under emulated encapsulation every rule is rewritten with generated scoping attributes:
/* what the source says */
:host { position: absolute; }
/* what the browser receives */
[_nghost-ng-c2570364828] { position: absolute; }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. Nonces avoid that, but need a server rendering HTML per response, which rules out static hosting. So a strict style-src effectively required 'unsafe-inline'.
As of v19.3.0 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 { … } (#329). The emitted CSS is byte-for-byte what's in the source, so it can be hashed once:
// collect the hashes for style-src from a running build
await Promise.all(
[...document.querySelectorAll('style')].map(async (s) => {
const digest = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(s.textContent));
return `'sha256-${btoa(String.fromCharCode(...new Uint8Array(digest)))}'`;
}),
);Content-Security-Policy: style-src 'self' 'sha256-…' 'sha256-…'
Verified against a production build served with a real, enforced header: with the collected hashes everything renders and a full drag-to-connect gesture works — zero violations, zero 'unsafe-inline'.
One scoping subtlety is covered by a follow-up and a regression spec: emulated encapsulation limited rules like :host svg to the component's own template, so the shipped rules use the child combinator (f-connection > svg) — projected user content (custom svg[fMarker] markers, icons inside [fConnectionContent]) keeps its own layout.
The connection worker shuts down with its flow
The connection 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 applications that open and close editors — a dialog with a flow inside, a tab switcher, a router that recreates the page — that was 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.
Upgrade notes
- No breaking changes.
- Library rules lost the specificity that emulated scoping attributes added — application overrides that previously lost a specificity tie may now win. If you override library internals, a quick visual pass after upgrading is worth it.
- To adopt a strict CSP: build, collect the injected style hashes, and ship
style-src 'self' 'sha256-…'. No nonce infrastructure required.
Thanks
@chris-perry — the CSP argument in #329 was one of the best-argued reports this project has received, and both pull requests (#333, #334) followed the library's architecture closely enough that review only had to guard the edges.
If Foblex Flow is useful to you, a ⭐ on the repo helps a lot 🙌
Full changelog: CHANGELOG.md