flowsvg 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/CHANGELOG.md +54 -1
  2. package/PATTERNS.md +71 -4
  3. package/README.md +148 -438
  4. package/README.zh-CN.md +148 -438
  5. package/dist/adapters/react.d.ts +55 -0
  6. package/dist/adapters/react.js +138 -0
  7. package/dist/adapters/vue.d.ts +158 -0
  8. package/dist/adapters/vue.js +177 -0
  9. package/dist/adapters/web-component.d.ts +111 -0
  10. package/dist/adapters/web-component.js +425 -0
  11. package/dist/{player-controls.d.ts → browser/controls.d.ts} +7 -3
  12. package/dist/{player-controls.js → browser/controls.js} +23 -31
  13. package/dist/browser/export-controls.d.ts +32 -0
  14. package/dist/browser/export-controls.js +151 -0
  15. package/dist/browser/player.d.ts +77 -0
  16. package/dist/browser/player.js +412 -0
  17. package/dist/browser/select-control.d.ts +33 -0
  18. package/dist/browser/select-control.js +171 -0
  19. package/dist/browser.d.ts +5 -69
  20. package/dist/browser.js +3 -353
  21. package/dist/core/color.d.ts +3 -0
  22. package/dist/core/color.js +18 -0
  23. package/dist/core/diagram.d.ts +40 -0
  24. package/dist/core/diagram.js +481 -0
  25. package/dist/core/edge-geometry.d.ts +45 -0
  26. package/dist/core/edge-geometry.js +609 -0
  27. package/dist/{core.d.ts → core/model.d.ts} +37 -61
  28. package/dist/core/model.js +1 -0
  29. package/dist/core/node-content-measurement.d.ts +34 -0
  30. package/dist/core/node-content-measurement.js +66 -0
  31. package/dist/{node-content-paint.d.ts → core/node-content-paint.d.ts} +2 -2
  32. package/dist/{node-content-paint.js → core/node-content-paint.js} +11 -20
  33. package/dist/{node-content.d.ts → core/node-content.d.ts} +18 -1
  34. package/dist/{node-content.js → core/node-content.js} +30 -6
  35. package/dist/core/svg-number.d.ts +5 -0
  36. package/dist/core/svg-number.js +7 -0
  37. package/dist/{theme.d.ts → core/theme.d.ts} +6 -0
  38. package/dist/core/theme.js +17 -0
  39. package/dist/{timeline.d.ts → core/timeline.d.ts} +11 -5
  40. package/dist/{timeline.js → core/timeline.js} +30 -22
  41. package/dist/core/validation.d.ts +11 -0
  42. package/dist/core/validation.js +399 -0
  43. package/dist/export/browser.d.ts +9 -0
  44. package/dist/export/browser.js +172 -0
  45. package/dist/export/captions.d.ts +18 -0
  46. package/dist/export/captions.js +44 -0
  47. package/dist/export/plan.d.ts +25 -0
  48. package/dist/export/plan.js +94 -0
  49. package/dist/export/types.d.ts +64 -0
  50. package/dist/export/types.js +9 -0
  51. package/dist/export/worker-source.d.ts +1 -0
  52. package/dist/export/worker-source.js +1 -0
  53. package/dist/export.d.ts +3 -0
  54. package/dist/export.js +2 -0
  55. package/dist/index.d.ts +7 -1
  56. package/dist/index.js +3 -1
  57. package/dist/node/cli.d.ts +2 -0
  58. package/dist/node/cli.js +72 -0
  59. package/dist/node/gif.d.ts +16 -0
  60. package/dist/node/gif.js +184 -0
  61. package/dist/node/html.d.ts +19 -0
  62. package/dist/node/html.js +61 -0
  63. package/dist/node/output.d.ts +2 -0
  64. package/dist/node/output.js +22 -0
  65. package/dist/node.d.ts +6 -0
  66. package/dist/node.js +3 -0
  67. package/dist/portable/LICENSE.esbuild.txt +21 -0
  68. package/dist/portable/LICENSE.flowsvg.txt +21 -0
  69. package/dist/portable/LICENSE.gifenc.txt +21 -0
  70. package/dist/portable/export.js +5 -0
  71. package/dist/portable/manifest.json +36 -0
  72. package/dist/portable/player.js +2 -0
  73. package/dist/portable/styles.css +227 -0
  74. package/dist/react.d.ts +3 -48
  75. package/dist/react.js +2 -126
  76. package/dist/styles.css +194 -14
  77. package/dist/vue.d.ts +3 -132
  78. package/dist/vue.js +2 -161
  79. package/dist/web-component.d.ts +3 -103
  80. package/dist/web-component.js +2 -396
  81. package/docs/images/entity-graph.png +0 -0
  82. package/docs/images/facts-timeline.png +0 -0
  83. package/docs/images/facts-timeline.zh-CN.png +0 -0
  84. package/docs/images/flowsvg-wordmark.gif +0 -0
  85. package/docs/images/node-content.png +0 -0
  86. package/docs/images/numbered-list.png +0 -0
  87. package/docs/images/numbered-list.zh-CN.png +0 -0
  88. package/docs/images/quick-start.png +0 -0
  89. package/docs/images/record-tags.png +0 -0
  90. package/package.json +38 -6
  91. package/dist/core.js +0 -1149
  92. package/dist/theme.js +0 -6
  93. /package/dist/{player-accessibility.d.ts → browser/accessibility.d.ts} +0 -0
  94. /package/dist/{player-accessibility.js → browser/accessibility.js} +0 -0
  95. /package/dist/{player-lifecycle.d.ts → browser/lifecycle.d.ts} +0 -0
  96. /package/dist/{player-lifecycle.js → browser/lifecycle.js} +0 -0
  97. /package/dist/{svg-dom.d.ts → browser/svg-dom.d.ts} +0 -0
  98. /package/dist/{svg-dom.js → browser/svg-dom.js} +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,58 @@
1
1
  # Changelog
2
2
 
3
+ ## Unreleased
4
+
5
+ - Place the animated FlowSVG wordmark first in centered headers in both SDK READMEs. Use larger text inside a compact frame, a closely cropped 50 fps GIF, and a closed signal loop at the upper-right corner. Ship the shared GIF under `docs/images/` and rewrite relative Markdown and HTML image paths to the versioned npm CDN URL during release verification.
6
+
7
+ ## 0.2.0 - 2026-10-22
8
+
9
+ ### Timing and rendering changes
10
+
11
+ - A beat with one flow now lasts for distance-based movement plus a 500 ms post-arrival interval, replacing authored `durationMs`. Movement targets 180 diagram units/second with a 400 ms minimum. Receiver paint fades in for 200 ms, holds for 100 ms, then automatic node/edge highlights fade out for 200 ms. Explicit highlights retain authored timing; reduced motion skips fades. Multi-flow and no-flow beats retain authored timing. Use the frozen public `Diagram.beats` schedule for effective boundaries and separate no-flow beats for longer reading.
12
+ - Orthogonal routes use rounded bends, centered clear bridges, separate stable incoming tips and stroke-aware arrow approaches. Curved inputs also retain stable separate tips. SVG paths, markers, labels, bounds and hit testing share the same geometry.
13
+
14
+ ### Added
15
+
16
+ - Browser GIF export through `flowsvg/export`, with snapshot inputs, range/speed/dimensions/captions, progress, cancellation, frame limits and an inline encoding worker. Optional player download controls work across Native, React, Vue and Web Component integrations; ordinary playback loads no encoder.
17
+ - Node 20+ `flowsvg/node` and CLI for standalone offline HTML and Chromium-based GIF export. HTML can embed optional GIF controls. GIF tasks use explicitly prepared Chromium or a caller-owned browser. Exports clean up task resources; CLI publication is atomic and preserves existing files unless overwrite is explicit. Copyable versioned portable assets include licenses.
18
+ - Opt-in live Loop playback and accessible Loop controls across integrations and portable HTML. Preserve elapsed remainder and speed at automatic wraps. GIF repetition remains independent.
19
+ - Deterministic DOM-free `measureNodeContent` and public measurement types for fixed-width authoring across explicit content versions. Preserve diagnostics and caller inputs; reject unrepresentable heights with field-path `DiagramValidationError`.
20
+ - Optional `viewport.fitHeight: { padding }` fits current painted geometry while retaining authored width and origin. Full-view SVG and playback fit height; GIF retains authored fixed dimensions and scale. Explicit focus retains authored viewport semantics.
21
+ - Optional `flow.highlightParticipants: false` suppresses automatic endpoint paint while retaining explicit highlights, edge paint and moving dots/capsules.
22
+ - Pill-shaped structured-content tags, reusable public `SelectControl`, opt-in compact controls, keyboard menus, refined control styles and responsive progress layout.
23
+
24
+ ### Fixed and verified
25
+
26
+ - Reject asynchronous GIF worker startup errors during pending rasterization. Release export resources on errors, cancellation and player destruction, and permit subsequent exports.
27
+ - Validate GIF options, effective captions and final encoded-frame limits before resource allocation. Preserve inherited state, range-end pictures and cumulative centisecond timing.
28
+ - Preserve content diagnostics for large block collections and avoid fractional-origin false positives in graph-label height checks.
29
+ - Keep SDK tests and release gates independent of showcase data. Verify cold packaging, file allowlists, DOM-free imports, strict consumer types, minimum framework versions, all four integrations and real offline HTML/GIF output through the installed tarball.
30
+
31
+ ## 0.1.1 - 2026-10-20
32
+
33
+ - Adopted thin neutral node borders, gray edges and blue emphasis in both themes. Separate highlight fills from borders and flow markers, remove the node-label halo, and refresh README previews.
34
+
35
+ - Expanded the quick-start document to a six-node order workflow with authorization, persistence, asynchronous events and reverse responses.
36
+
37
+ - Added SDK-rendered previews beside the quick-start, structured-content, list, entity-graph and Facts timeline examples in both package READMEs.
38
+
39
+ - Include the eight README preview images in the npm tarball. Source READMEs use relative image paths for local previews; the release verifier prepares staged README copies with versioned npm CDN URLs for public readers. Release verification requires every preview and rejects undeclared documentation assets.
40
+
41
+ - Removed local build, source-layout and release instructions from the package READMEs; repository documentation retains the contributor workflow.
42
+
43
+ - Completed bilingual module navigation, updated migrated test links, and consolidated architecture implementation and verification records.
44
+
45
+ - Grouped React, Vue, and Web Component implementations under `src/adapters/` while keeping explicit root entries, shared Web Component registration identity, SSR-safe imports, lifecycle behavior, and cross-host integration tests. Updated nested release artifacts and consumer references.
46
+
47
+ - Grouped the browser player implementation and its controls, accessibility, lifecycle, and SVG DOM modules under `src/browser/` while preserving the `flowsvg/browser` entry, lifecycle behavior, DOM-free imports, and public player contract. Updated browser tests and release allowlists for nested build output.
48
+
49
+ - Moved shared hexadecimal color interpolation to the pure `src/core/color.ts` module. Timeline evaluation and diagram paint share the same runtime helper; content painting checks contrast without a timeline dependency.
50
+
51
+ - Centralized edge routing, path sampling, distance queries, label anchors, hit testing, and SVG number formatting in `src/core/edge-geometry.ts` and `src/core/svg-number.ts` while preserving the existing public frames and SVG output.
52
+
53
+ - Organized the platform-independent core into shared model, document validation and diagram orchestration modules. Preserved all public values/types, error identity and evaluation behavior; grouped core tests with their implementation.
54
+ - Preserved nested JavaScript and declaration build output and replaced the release file pattern with an explicit module allowlist that rejects source, tests and unrelated files.
55
+
3
56
  ## 0.1.0 - 2026-10-17
4
57
 
5
58
  - Added a release CLI that runs type checks, SDK and release-script tests, tarball consumer verification, example builds and npm publication preview. Default to preview; require `--publish` for upload, and publish the exact verified tarball retained in `dist/releases/`.
@@ -9,7 +62,7 @@
9
62
  - Prepared the first npm release with repository metadata, public registry settings, bilingual package documentation, automatic prepack builds and prepublish type/test checks.
10
63
  - Verify packaging from a missing `dist`, every exported JavaScript/type/CSS target, the file allowlist, framework-free imports, strict consumer types and all four host lifecycles.
11
64
 
12
- - Renamed the package and SDK directory to `flowsvg` (流形). Player exports now use the `Flow` prefix: `FlowPlayer`, `FlowPlayerProps`, `FlowPlayerHandle`, `FlowPlayerElement`, `defineFlowPlayer()` and `FLOW_PLAYER_TAG`. The default element is `<flowsvg-player>`; CSS classes and control variables use `flowsvg-` and `--flowsvg-`. Imports, selectors and public API references must use the new names.
65
+ - Renamed the package and SDK directory to `flowsvg`. Player exports now use the `Flow` prefix: `FlowPlayer`, `FlowPlayerProps`, `FlowPlayerHandle`, `FlowPlayerElement`, `defineFlowPlayer()` and `FLOW_PLAYER_TAG`. The default element is `<flowsvg-player>`; CSS classes and control variables use `flowsvg-` and `--flowsvg-`. Imports, selectors and public API references must use the new names.
13
66
 
14
67
  - Fixed cylinder SVG fills by rendering the top cap as a separate filled ellipse inside the same node interaction group, so the cap no longer appears hollow.
15
68
 
package/PATTERNS.md CHANGED
@@ -1,12 +1,75 @@
1
1
  # Patterns
2
2
 
3
+ - Prepare 0.2.0 from the SDK package version and verify its exact tarball before publication. Treat compiled `Diagram.beats` as the timing contract when migrating from 0.1.x; keep authored no-flow reading beats independent. Release notes describe the final 500 ms post-arrival interval. Repository release documentation distinguishes a prepared version from npm latest.
4
+
5
+ - Derive single-flow post-arrival time from the 200 ms entrance, 100 ms full-paint hold and 200 ms departure constants. Evaluate departure independently of logical flags and marker progress; multiply automatic node/edge paint by the remaining weight before merging explicit highlight paint. Reduced motion bypasses both paint interpolations without changing compiled intervals.
6
+
7
+ - Resolve automatic flow participant paint separately from logical membership. Single-flow senders paint immediately; receivers use a deterministic 200 ms cubic transition after movement, then automatic node/edge paint fades out during the final 200 ms. Merge paint weights with explicit highlights using max, retain logical membership at zero paint, and bypass flow paint interpolation for reduced motion and synchronized multi-flow beats. Keep this in core evaluation so static SVG, browser playback and export sample the same colors.
8
+
9
+ - Separate single-flow movement from arrival hold: effective duration is reference movement plus 500 ms, replacing the authored beat duration. Keep no-flow reading and multi-flow durations authored. Cap opening transitions at effective beat length so shortened beats finish their updates before the next snapshot.
10
+
11
+ - Compile authored snapshots first and route each single-flow beat at its target visual state through ordinary frame geometry. Use that path length once to derive reference movement time, then compile effective intervals without changing source documents. Cap transitions at effective beat length. Keep movement progress separate from full-beat progress; clamp arrival while retaining beat-local highlights. Export frozen `Diagram.beats` metadata for all schedule consumers, including browser steps, scene menus and GIF caption preflight. Reject non-finite movement or accumulated timing at the affected beat duration path. Multiple flows keep authored synchronized timing; reduced motion changes visuals only.
12
+
13
+ - Keep live loop preference in the browser player, outside diagram documents and GIF options. Wrap only automatic positive-duration advancement, preserving elapsed remainder and speed. Explicit end seeks pause; play from the end restarts only with loop enabled. Forward dynamic adapter changes through `setLoop`, emit only `loopchange` for mode changes, and use the same scheduler in portable HTML. Recheck playback intent after synchronous restart events so a listener’s pause, seek, load or destruction wins.
14
+
15
+ - Fit optional full-view height after current geometry and paint resolve. Keep origin and authored width; include stroke, exact cubic vertical extrema, exact marker orientation, label descent/halos and active flow capsules. Round outward to whole units, validate the combined finite result, and fall back to authored height for empty frames. Focus retains authored aspect and bounds. GIF validates the original option, then compiles a private snapshot without height fitting so all encoded frames share authored scale.
16
+
17
+ - Round orthogonal routes after obstacle routing. Serialize quadratic bends and sample the same controls for flow distance, labels, bounds and hits. Clamp neighboring trims, reserve the straight marker approach, and reject control hulls that intersect stroked endpoint or obstacle bounds; tight corridors may reduce a bend to zero.
18
+
19
+ - Measure node content while authoring documents, then store explicit dimensions. Share complete consumed block height and unresolved block overflow with fixed-size layout; never infer height from the final baseline. Measure against saturated contour clearance so nonempty cylinders reserve both full cap diameters. Combine explicit versions with their maximum required height, preserve every version/block diagnostic, and reuse nested content validation before layout. Aggregate height maxima and diagnostic entries without expanding authored collections into function arguments. Validate each computed required height before returning; individually finite source values can overflow combined height arithmetic. Accumulate a `DiagramValidationError` issue at each affected `content[index]` path, and keep finite representable results supported. Apply the existing geometric overflow tolerance to outer vertical bounds and graph-label top bounds so changing the authored origin does not create floating-point height warnings. Keep measurement independent of scene scanning, DOM, fonts, clocks and example data.
20
+
21
+ - Keep natural outside-channel clearance separate from endpoint stub reservations. Compute the ancestor-aware lane with the base arrow clearance, then clamp it outward to cover both endpoint stubs; do not add the bend radius to ancestor clearance.
22
+
23
+ - Try centered orthogonal bridges and single outside channels before grid search. Validate candidates against expanded obstacles and endpoint reservations. Include separate ancestor bounds for outside clearance; exclude shared ancestors and keep group interiors traversable.
24
+
25
+ - Share target position allocation between curved and orthogonal routes. Apply the allocated position before constructing curve controls so cardinal arrival tangents remain exact; keep hidden inputs in each side group.
26
+
27
+ - Allocate curved and orthogonal target slots from all declared incoming edges on each resolved side, independently of timeline visibility. Order slots by source position, with document order breaking ties. Keep slots in the side's central portion and follow ellipse/cylinder contours. For orthogonal routes, share the SVG marker footprint with routing and extend the endpoint obstacle through the reserved straight arrow approach so grid search cannot fold back into it. Pass evaluated stroke width to geometry. Cap reserved segments by available space in front of each port; narrow endpoint gaps must not cause backtracking through a node.
28
+
29
+ - Keep tag shape in the shared content model. Resolve pill corners from final tag height during SVG serialization, after wrapping and baseline alignment. Shape must not change text layout, colors or hit targets; omitted shape keeps rounded corners.
30
+
31
+ - Reuse `SelectControl` for select-only choices. The caller owns the committed value; keyboard navigation only previews until Enter/Space commits. Keep listbox selection separate from active focus, close on blur/outside press/disable, and destroy menus before removing their host. Render options as text and preserve hidden menus.
32
+
33
+ - Keep control presentation in `styles.css`; use `flowsvg-play-toggle` as the Play/Pause styling hook instead of matching translated labels or DOM position. Preserve CSS variable customization, 44-pixel default targets, opt-in `flowsvg-compact` sizing, visible keyboard focus, native range semantics and hidden export states. Put progress on its own row at narrow widths and disable decorative transitions for reduced-motion users.
34
+
35
+ - SDK runtime, build, tests, browser acceptance and package artifacts must own their inputs. Keep test fixtures inside the SDK and exclude them from runtime compilation. Preserve generic assertions while moving authored story wording and narrative structure to example-owned acceptance. Release verification must not build apps or private showcase packages. The browser regression runner serves only the SDK directory so external author imports fail visibly.
36
+
37
+
38
+ - Observe GIF worker errors immediately after construction and retain the failure for the entire task. Race image decoding and worker replies with that failure as well as caller cancellation; remove all listeners and release task resources on every exit path. Request-scoped error listeners alone can miss startup errors during rasterization.
39
+
40
+ - Keep release acceptance at the installed artifact boundary: copy the portable consumer verifier beside the real tarball install, then copy complete built tools/runtime dependencies away from package source. Use prepared executable paths, offline browser contexts and independent GIF decoding; never satisfy release checks by inspecting source or downloading browsers during tests. Explicitly select Node/React type libraries in strict consumer compilation.
41
+
42
+ - Assemble optional GIF HTML in the Node HTML renderer by reading the same build’s `portable/export.js` before `portable/player.js`. Snapshot and validate the boolean `gifExport` option before asynchronous reads. Forward it through the inert bootstrap payload; reuse the existing player controls and exporter without importing automation or embedding a second encoder. Default HTML reads no GIF asset.
43
+
44
+ - Node GIF export dynamically imports the pinned `playwright-core` runtime dependency only when launching Chromium. Reuse the pure browser planner before launch, then run the versioned `portable/export.js` inside a task-owned offline context/page. Snapshot documents/options synchronously. Close the context on abort, share its closing promise, close owned browsers including late launch results, and always remove temporary files. Never close a caller-owned browser. Route CLI HTML/GIF through one atomic publisher; exclusive links preserve existing files, and only explicit overwrite uses rename.
45
+
46
+ - Keep optional GIF UI in `browser/export-controls.ts`. Reserve one task slot and capture the validated document and resolved theme before the first asynchronous boundary. Race module loading with abort, guard callbacks/downloads by task identity, and abort on player destruction. Document loads retain the old task; adapter option changes replace and destroy the old player. Reuse core JSON serialization for source snapshots so Vue reactive documents work without importing Vue into the browser player.
47
+ - Keep the browser export import dynamic in emitted ESM. The portable IIFE build replaces only the export-controls import with an internal bridge to `FlowSVGExport`; basic HTML does not include exporter/worker code. GIF-enabled HTML must explicitly embed the separate same-version exporter asset. Keep this assembly detail out of public player options.
48
+
49
+ - Validate supplied GIF option types before applying defaults or checking cancellation. Keep dimensions, sample counts and 16-bit hold-delay split counts in the pure planner so browser and Node reject limits before allocating rendering resources. Evaluate range samples on the full original timeline, clamp ordinary samples below the exclusive endpoint, and use the immediate IEEE-754 predecessor for an intermediate end-left hold. Preserve global completion with zero additional delay. Allocate delays from rounded cumulative centiseconds and bound final encoded frames, including hold splits, at 1801.
50
+ - Preflight GIF captions by walking every overlapping source beat interval with inherited caption state, including intervals missed by sampling. Load the effective caption glyphs before measuring with the same font, wrapping, line height and padding used to paint. Preserve explicit blank lines and empty-string captions. Reject horizontal or vertical overflow with scene/beat context instead of clipping or reducing the font.
51
+
52
+ - Keep browser GIF export under `src/export/`, with the public `src/export.ts` entry and a separate `portable/export.js` IIFE. Core, ordinary browser playback and base offline HTML must not eagerly load the exporter or encoder. Bundle `gifenc` only into an inline Blob worker; transfer one RGBA frame and await acknowledgement before sampling another. Keep timing/dimension planning pure, share core SVG evaluation and font/palette values, snapshot input before awaiting, and release canvas, images, object URLs, listeners and workers in every exit path. Race pending browser font/image work with AbortSignal so cancellation does not wait for those services.
53
+ - Run SDK test files sequentially because offline integration files rebuild the shared `dist` directory. Use the independently maintained `gifuct-js` decoder for actual GIF pixels and raw GCE fields for delay assertions; its decompressed delay normalizes zero values and must not be used to verify metadata.
54
+
55
+ - Keep default diagram colors and line metrics in the core theme. Use separate highlight fill, border/marker and marker-text colors so active nodes retain readable text in both themes. Browser hover consumes the same theme values; preserve border-only hover by default. Node labels have no halo; edge labels retain background isolation where paths cross text.
56
+
57
+ - Keep README previews and the animated brand asset in `docs/images/` inside the SDK package. Enumerate every expected PNG and GIF asset in the release verifier; require each image and reject undeclared files. Place the logo first in a centered HTML header in both README languages. Use relative image paths in source READMEs for local previews. The release verifier unpacks the built package into a temporary directory and converts Markdown image paths and HTML image sources only in its README copies to npm CDN URLs with the package version. Repack without lifecycle scripts, require the packed file set to remain unchanged, then verify and retain that final tarball. Source READMEs must remain unchanged by release verification.
58
+
59
+ - Keep shared document/frame types in `src/core/model.ts`, document validation and its single error class in `validation.ts`, and compilation, cloning/freezing, evaluation, SVG and hit-test orchestration in `diagram.ts`. Node-content types and nested validation remain in `node-content.ts`. Import runtime owners directly; use type imports for shared model dependencies.
60
+ - Enumerate public values and types in the root entry, including `wrapText`, `Diagram` and all node-content types. Keep core contract tests in `src/core/` and consume public entries. Separate core, browser, React, Vue and Node TypeScript builds preserve the internal directory hierarchy under `dist`; check worker types separately before bundling its source. Enumerate each emitted module in the release allowlist instead of accepting arbitrary files below `dist`.
61
+ - Keep the browser player implementation under `src/browser/player.ts`, with controls, accessibility, lifecycle, and SVG DOM synchronization beside it. Keep `src/browser.ts` as the explicit public entry; browser tests use that entry while core remains DOM-free.
62
+ - Keep React, Vue, and Web Component implementations under `src/adapters/`; root adapter files are explicit public entries that export the single implementation and preserve runtime identity. Adapter tests live beside their implementations and cross-host business scenarios live under `tests/integration/`; imports use public entries.
63
+ - Keep color interpolation in the pure `src/core/color.ts` module. Timeline and diagram painting import it directly so generic color rules do not depend on timeline semantics. Content highlight paint retains theme-specific semantic colors and adjusts default ink only when the evaluated fill requires more contrast.
64
+ - Keep route construction, path measurements, label anchors, and path hit testing in `src/core/edge-geometry.ts`; share integer and three-decimal formatting through `src/core/svg-number.ts`. Diagram orchestration consumes these internal results without exposing geometry.
65
+
3
66
  - Run release gates sequentially through the root release CLI. Default to a preview without authentication; check authentication before the gates only for explicit publication. Copy the verified tarball after all consumer checks pass, then preview and publish that file without repacking. Stop on any command failure and keep npm stdio attached for authentication prompts.
4
67
 
5
68
  - Build Vue declarations against the pinned minimum supported version, 3.5.0; newer Vue patch releases can add inferred `DefineComponent` type parameters that older consumers cannot read. Verify both minimum and current framework versions in the packed-package consumer.
6
69
 
7
70
  - Build through `prepack` so `npm pack` and directory publishing cannot use missing or stale artifacts. Keep publish-only type/test checks separate from packaging to avoid recursive release verification. Verify the packed exports and strict consumer types before publishing.
8
71
 
9
- - Publish the SDK as `flowsvg` from `packages/flowsvg`. Use the `Flow` prefix for player exports, `<flowsvg-player>` for the default custom element, and `flowsvg-` / `--flowsvg-` for CSS classes and control variables. Keep package imports, declarations, examples and release verification aligned with these names.
72
+ - Use FlowSVG as the display name. Publish the SDK as `flowsvg` from `packages/flowsvg`. Use the `Flow` prefix for player exports, `<flowsvg-player>` for the default custom element, and `flowsvg-` / `--flowsvg-` for CSS classes and control variables. Keep package imports, declarations, examples and release verification aligned with these names.
10
73
 
11
74
  - Apply hover to stroke only by default for every node and group. Preserve core fill and content paint, including active flow or explicit highlights. With `hoverFill: true`, paint fill and readable content as well. Forward the same option through every adapter and restore the current core SVG when the pointer leaves.
12
75
 
@@ -33,14 +96,14 @@
33
96
 
34
97
  - Keep structured node content in a deterministic module that accepts current absolute geometry and a resolved theme. Return the complete layout plus a nonnegative safe area, then consume those same lines and clip geometry in SVG. Keep content child groups keyed separately from the node shape; only the shape uses its node `data-id`. Validate controlled nested fields before cloning, and preserve simple-label overflow behavior.
35
98
 
36
- - Preserve collinear extrema when compacting path points: a reversal contributes distance and bounds even when all samples lie on one axis. For explicit orthogonal ports, reserve outward endpoint stubs before grid search and include inflated endpoint bodies among middle-route obstacles; leave fully automatic routing unchanged.
99
+ - Preserve collinear extrema when compacting path points: a reversal contributes distance and bounds even when all samples lie on one axis. For all orthogonal ports, reserve outward endpoint segments before grid search and include inflated endpoint bodies among middle-route obstacles. Reduce reserved segments in narrow gaps so stubs do not enter the opposite node.
37
100
 
38
101
  - Keep hover in the browser paint layer: restore the current core SVG before applying a hovered node's shared-theme highlight colors. Re-hit the saved screen position through the updated camera after each frame. Include nonempty node label bounds using the capsule's shared width estimate for wide characters. Clear interaction causes on pointer cancellation, successful load, and destroy. Never write hover into the core frame or timeline; removing hover must expose the current explicit/flow highlight or ordinary style.
39
102
  - Render transfer text from the evaluated beat-local `flow.text`, without changing the edge label. Estimate capsule width by Unicode code points with full-em space for wide characters, retain horizontal text, escape plain SVG content, and disable marker pointer handling. Verify current browser messages and static SVG equality with `tests/browser-flow-text.html`.
40
103
 
41
- - Treat each beat’s transfers as a synchronized group: derive all marker positions from the same linear progress and union endpoint highlight reasons. Reject a second flow for the same edge regardless of direction or other field errors; keep flow assignments separate from visibility, explicit highlights, and base updates.
104
+ - Treat multiple transfers in a beat as a synchronized group: derive their marker positions from the same linear progress and union endpoint highlight reasons. Reject a second flow for the same edge regardless of direction or other field errors; keep flow assignments separate from visibility, explicit highlights, and base updates.
42
105
 
43
- - Compile `flow` actions as beat-local state: use the full beat progress for distance-based marker sampling, keep static edge arrows unchanged for reverse transfers, and derive temporary edge/endpoint highlights during frame evaluation so they expire without overwriting explicit highlights or ordinary style updates.
106
+ - Compile `flow` actions as beat-local state: sample markers by movement progress for a single transfer and full-beat progress for multiple transfers, keep static edge arrows unchanged for reverse transfers, and derive temporary edge/endpoint highlights during frame evaluation so they expire without overwriting explicit highlights or ordinary style updates.
44
107
  - Generate curved routes from cardinal port normals and use the same sampled geometry for path consumers. Keep endpoint control points on the outward side of each port so the path enters the target along the inverse normal; separate reverse relationships with a deterministic perpendicular lane.
45
108
 
46
109
  - Keep the native business example in a fixed view: use the same document across public integration checks, synchronize three request paths then two processing paths, and return messages through reverse flows and a separate response relationship. Compare public frame/SVG output at beat boundaries rather than adding adapter clocks or test-only APIs.
@@ -99,3 +162,7 @@
99
162
  - Validate every document field and reference before compilation; reject unsafe colors and duplicate timeline assignments with field paths.
100
163
  - Route orthogonal edges against evaluated absolute geometry and inherited visibility; exclude group frames from obstacles and serialize direction markers with the same paths.
101
164
  - Build each evaluated edge once as internal path geometry with its serialized path, points, length, bounds, and distance-based sampling; use that geometry for labels, focus bounds, hit testing, and active flow sampling so consumers cannot drift apart.
165
+
166
+ - Build portable browser assets with an explicit esbuild entry and a same-version manifest. Node HTML assembly reads only built assets and core modules; browser automation and GIF dependencies stay outside this path. Snapshot and validate document/options before asynchronous reads, embed JSON as inert escaped data, and escape page titles separately. CLI writes a sibling temporary file, then links without replacement or renames only when overwrite is explicit. Always remove temporary files on publication failure.
167
+
168
+ - Compile `flow.highlightParticipants` with default true. Apply this policy only to temporary endpoint highlights; keep explicit node highlights, temporary edge highlights and marker evaluation independent. State-machine stories can then animate event transfers while retaining one current state. Reduced motion suppresses markers and retains configured highlights.