Skip to content

About

Stickyflow.js is a framework-independent parser, renderer, and editing runtime for using SFL in browsers, Node, and your own applications.

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@*-  -                *                                       =                                            .         *@
@@*++-::-::-:::::---::.:.:::::::::::-:::::-::::-:---:-:.   .@@@@@@@.   ::::::---:-:::::::::---::::::--:--:-:::::---:: %@
@@ .::---::::::-::::::::::-:::::::::::::::-:::::::::.   -@@@@@: -@@@@@+   :::------:-::-::-:::.:::::::::::-::---::-:: #@
@@*-::::.:::-::::::::-----::::::::-::::::::-:-:::.   *@@@@@    -*+-+@@@@@*   .::::-::::--:::::-:::::-:-::::-:-::::::: %@
@@.----:--::::::::::::::::-:::::::::.::::--::.   .%@@@@%   .::.-%***+-+@@@@@%.   ::::----:::::::::::::-::::::::::::-: %@
@@ ------:-:::-::::::-::::-:-::::::-::-::..   +@@@@@@   .-:::::-%*%*%**:  %@@@@@+   :::-:---::-::::::::::.:::::::-::- *@
@@ .:-:-::-:-::::::-:::-:::::::::::::::    *@@@@@*@@@-.-:-::::.-%%*%**%-.:   +@@@@@*   .--::::::-::::::::::::::::::.: %@
@@.:.-:---:::::::-::-::::::::::::::.    @@@@@%+. +@@@-:-::-::.:+**%*%%**.-::. @@@@@@@@%   .::::-:::::::::::::::-::.:: %@
@@:-----::-::::::::-::.:::::::::.   -@@@@@*--    +@@@-.:::-:+*.+=%%**%%+::--: @@@@@@@@@@@@   .:.::::::.:--::-::-:---- %@
@@ .:::.-:::::::::::---::::::    -@@@@@.:-. .    +@@@-.---:. *-+*=*%%%%-.:-::.@@@@@@@@@%@@@@@    ::::::-:::::--:::::: %@
@@ ::::::::-::::::--:::::.    %@@@@@ :+-:  .-%%@ =@@@+.::..*%:-@*#*+%*%+.::::.@@@@@@*@@@@@#@@@@@.   .::-:-:-::::::::: %@
@@:::::::::::::::-::-:.   -@@@@@* -++   +@%@**%@ *@@@-.-:*%*+#%+*+*%%%%+.:-::.@@@@@@@@@@@@@@@@@@@@@+   .:--:::::::::: %@
@@ .::::::-::.::::..   *@@@@@*.---  .   -@@@*%*- *@@@-.:.. +*%**%#***##+.---:.@@@@@@@@+   -@@@@@@#@@@@%   .:::::::::: %@
@@ ::::-:::::::.    #@@@@#-   :-*@@ .+@%.@%:-.   *@@@.     .. -*+%##@#@=.-:-:.@@@@@@%  ::.***@@@@   %@@@@#.   .::--:: %@
@@ :::-:-:::.   .@@@@@@   ::: . #@@ %@@++   -@--:*@@@%@@@@ .:*=**-*%%#@+.:--..@@@@@@: ::..%%*@@@@ ...  :@@@@@-   .::: %@
@@ .:::-::   -@@@@@@@@@ ::--- . @@@-    -##-+@*- *@@@@@@@@:  - -  *%%%#+.--:::@@@@@@:.-:- %%*@@@@...-+- **+@@@@@+   . %@
@@ :::    +@@@@#@@@@@@@ -----..    %@@+ *@@+  %  *@@@  #=  @@%.-  *%*@@=.::::.@@@@@@: :-:.%%%@@@@ ..-=* #***+-@@@@@=  *@
@@ .   %@@@@%%@@@@@@@@@ -----.... .-@@**-   -@:  =@@@.   @@@@+ . -@@@::-=+-:..@@@@@@@ .:: %*%@@@@ :.+=+ #%*%*%+* #@@@@@@
@@ *@@@@@*   @@@@@@@@@@ ::--+ ...%@@:   *@%+ @+#@@@%@@@  @@@@@@@@@----+----%+:@@@@@@@@  . %%%@@@@...++*.%*%*%*%%-     *@
@@ -%@-  :--:@@@@@@@@@@ ----- . +   *@@.+@@@@@@@%*+  @@@@@@@@@@@@   -+*%*@@*@#%#@@@@@@@*  %*%@@@@ ..-**.%*%*%*%%+.:.- %@
@@ : ---+-+--@@@@@@@@@@ ---:-.. .@% %@#++:...+*+   #@@@@@@@@@@@@@  :. .@%-*%@@@%%%%#@@@@@ +**@@@@...=*% %%*%%%-+-:::: *@
@@ -.-*+-+-+:@@@@@@@@@@ ::-*-  . @**-+-++-     :@@@@@@@@@@@@@@@@@#+    %+ ..-+*@@##%%*@@@@@#+%@@@...=%*.%%%%+-=+--::- %@
@@ -.++---+::@@@%@@@@@@ ::.     .+-*-+   @@@@@@@@@@#@@@@*:*%#@@@@%%%%**++     .--*@@@#%%%*@@@@@@@...+*% %*%%:-::-::-- %@
@@ -.+-+--+-:#@@@@@@@@@ .  %@@@@*    %@@@@@@@@@@@@@@@@@@%   :-+*%%***+#@@@@@-   ..:--@@@##%%%@@@@...*%%.#*-*@%:+-:::- %@
@@ :.-+:-+---@@@@@@@@@@ :@@@@@@@@@@@@@@@@@@@@@@@@@@@@***% ....:%-  %@@@+   @@@@-.   .--+#@@%...-@:. +*% -::-+-.-+.::- %@
@@ ::+-+-----@@@@@@@@@@ .%==*@@@@@@@@@@@*@@@@@@@@***%%%%*:-.:.-    +@@@@#*@@@@@*%%*-    :--**+--=+*:*%%.%-:.---+-:::- %@
@@ :.*-+-+--:@@@@@@@@@@ .@@@@@%+#@@@@@@@@@@@@@@@@@%**%%%*.=:..+ :*-** -@@@@%. *%*%*%%*-. .   +*%-+. *%%.#+:+.:---:-:- %@
@@ ::+----+--@@@@@@@@@@ +  .%@@@@%*#@@@@@@@@@@@@@@@@@***#%=-  :  :+%%        -##@@%%%%%%%+. .  ...: *##::.*#* %%:::-- %@
@@ :.+++-----@@@@@@@@@.@@@@@   -@@@@*  #@@@@@@@@@@@%@@@@**%%#%*%%%%*=. ..    -=-- -%%%*%%%-    :::: *%#.-*%%%*@*:..-- %@
@@ :.+:-++--:@@@@@@@@@@   *@@@@%          *@@@@@@@@@@@@@@@@%+*%%%*%##%******%%%:. +#%%*%**%***:+-.:.*%%-*+. #@**@%--- %@
@@ ::=+------@@@@@@* %@@@@+   @@@*-....--:   -@@@@@@@@+  @@@@@%+*%*%%%##@##%%%% . :****%*%*+=-#*.::  *% :-#@%%*@%.:-- *@
@@ ::-+-+-+--@@@@@@@@+  -@@@@@+  :-....-----:.  .@%    .    @@@@@@***%%%%%%%*%*+-+*%*#**=*%@@@@% ::.*@%-+:-:-%+-:.::-.%@
@@ .:+-------@@@@  .@@@@@-  @%----+ ...---+----:.. .::.---::   #@@@@@%+**%*%*%*++-=**+%#@@@@@@@% :: *@@@@***-#-*%*-:- %@
@@ :.+--+-+-:@@%@@@@:  %@@@@- :--:-   .-+--+------::.::--=+---:   *@@@@@#+-+*%*%-+=@@@@@@@@@@@@+   .*@@@#: :+**-  -:- %@
@@ ..*-------@@:  *@@@@%  . -:-:..:-%%+**+--+-+-+-:::::--  -+--:::   -@@@@@@*--@@@@@@@@@@@% *##%*****%*#%:.. + .::-:- %@
@@ ::*+-+--. *@@@@%  -@@@#--:...#@%:   --+++--+--+.-:::-:.@-  :---:-:   :@@@@@@@@@@@@@%-  - :.-%%%%*%#@%%  . + .  %*- %@
@@ :-*+---+@@%  .@@@@@       @@*:.: ...+:-----.-+-::-::-:-@  %%. ---::::    @@@@@@@.-  -+-* --: ..%###%*%*+. - -%*-.: %@
@@ .:*--.  :@@@@@   @@- .*@@@@@ :-+ ...-+-.:%@%::+:::::::+%.@@@%+**--+----:.   *  .:*.-*+-*:%  .::..:*##%**%*@*:...:: %@
@@ .-*:-@@@@*  @@@@@+:#@@@@@@@@ ---....--:%@@@@@#-.:::.-.    -+ + --* .-------::..++% +*+-% @@@%:.:---:.*@%-. ..::::: %@
@@ .:***. -@@@@% .@@@@@@@@@@@@@ -:+ ...+-:%@@@@@@-:::..-: @*#- -+:*%@ ..   -+ ....+-%.-*+-* @@@@@@:-+----: ..:::::::: %@
@@ ..*@@@@@- :@@@@@@@@@@@*:@@@@ ---.. .---:%@@@*--..:..--.%#@@  %% -@.+: . *@@@-  ++% +**+* @@@@@@.--+-+---::::-:-::- %@
@@ :.@+  *@@@@@@@@@@@%=--=-@@@@ --+ ...-+--    :--.-++-::-.  +=-@@@@+ --.. *@@@@@%++% +*+-% @@@@@% *=+-+-+:::::-:::-- %@
@@...+%@@@@#@@@@@@*---==**+@@@@ ---....---------**%%+-@@-.:---  +%@*-..: . *@@@@@@*+% +**-* @@@@@# -::+=---::--:----- %@
@@ ::.  -@@@@@@@ :.:++****+@@@@ ---   .-::-++**%*-   :@@@@@:**=+-  -%.-- . *@@@@@@--%.-*+-* @@@@@#   : -**::--------- %@
@@ ::-: *@@@@@@@+@@@#+****+@@@@ :---+++-*+-%**       *@@@@: ..-****+. -: . %@@@@@@-*%.+=-**-@@@@@%*@@@@@ .--::-:-:--- *@
@@ ::-:.*@@@@@@@-@@@@#****-@@@@ *%%+=**##%.%*    .+#@%*=*@+   . .-*****+++:.*@@@@@-=*.:*+-*-%@@@@%@@%#@@@*.+--:---:-- %@
@@ .--:.*@@@@@@@-@@@@@***%-@@@@-=+-*@@@@@+ += +*@@@@##@#%%%##*-   ..-=**+--++:.-@@-=**:*%=**@#%@@%@@@@@@##- :+:::---- %@
@@ :--:.%@@@@@@@-@@@@@****-@@@@++++-+.   *@#@%%@@%*:   +%@######%-   ..:-%*******-*+**%****+*@@@@*.@@@@@@@@@  ---::-- #@
@@ ::-:.*@@@@@@@-@@@@@****+@@@@-**%.-. -=@@@@#+.    .*.   +%@@@#@#@%+      -*%-:  ***-*%**#+@%%@@% *@@@@#%@@@= -+-::- %@
@@ ::-:.%@@@@@@@-@@@@*****+@@@@:%%%*-     .:    .=*%%****.   -#@@@%%%@#%#@@+.   . ****-*%***@%--@%   #@@@@@@@@   -+.- %@
@@ .-+:.*@@@@@@@-@@@%+++-*@@   ---.*%**+: .  :%***+.  +*****.   .%@@#@%@@%--*-... **%+-#++%+@%@@@% :. +@#@@@@@@@-..=- *@
@@ :.--:*@@@@@@@-@@::+%@@@.-   -=++@#%%%%**#%***-:+@@#+--*%**%*.   :#@#%*-  .: .. *** -+-=+.@@@@@% -:: %@@@@@#@@*  :- %@
@@ ::--:%@@@@@@@::*@@@%..-.-*.-#* @@*-+%###**--+:@@@@@@%::.+***%**:   -%%...::   :%-*.:+--*--.*@@* .   .=##@@@@@@@  - %@
@@ .:+:.*@@@@@@@@@@*::--+-.*@@@@% @@%+++***++*+--      :*@*---=*%*%**-  .    -+**=***+.---*-+- .@* -#@@@%. @@@#@@@@@* %@
@@ ::--.*@@@@%%*::-+-+-:%@@@@@@@* @@%*%*#%*   -+*=+--@@@@%*#*+++++%*%*%++.-=++++=*%*%=*%=.+:   :@@@@@+ =*--@@@@@@@@*- %@
@@ .-+.:%@@#+  -***+-@@@@@@@@@@@* @::*%%*%*=-    .=**%@@@+*+*+:  :%*%%*%%***#%**+-+********:+@@@@+.  -+.-**@@#@.    . %@
@@ ::-:.**:+=. *#%%@@@@@@@@@@@@%  ---%%*%%%%%*+-    .-+-+*+      +%%**=++-*#**%=##++**#%%*@@@@@-   :+**:****+-+%+.::: *@
@@ ::---#+   *@*   @@@@@@@@@.   ::*%*#%%**%**%%%*=-    .     :+*@%=+*%**%*@%#@##**%###%*#*.  @@@@@=   +###%**%: ..:.: %@
@@ --+--#* ..  ... @@@@@@   .:-=+-*+-**%%%%%%*%%%%%**- .  -%%%%+-=*%%%*%*%**%**=-%%%%%%%%*--:   @@@@@*   -**+. .::::: %@
@@ ::::.**  .::...:@@*   --+***==+#*%++=+*%%*%*%*%%%%%%%%@%**==%%%%**%%%+--++-*+--:+%%%%%%.:---:   @@@@%+=@**%=-. ..- %@
@@.--*%@#*+:. ..--   .-*%@*****%**%*+***%*=*%%%%%*%*%%***-*%%%%*: +**-. :-++= ++++---:+*@%*+-::---.:@@@: .+-  .%#*+.- #@
@@  ..-*@#%**+-..:-*%#@@##%*%%**++*****%*%*%+*=*%%%%-***%%%**+  .---: *#*..-* ++++=*=++ +%++=**-...-@@@- .-.. .*##@%: %@
@@@#    .:%###%*%#%@@@##@#**++=****+**%**%%*****+++*%%%#* *#*=+++++-@@@@@@@-+ -++**+ *%*-@-+-+-***:-@@@*. .  -*@*:  . %@
@@@@@@@     -%@##%*##@@#@#*=*-++***#%***%**%%*%**%%%*:   :--+--+-++- *@@@* +***%   -#*@%-@+*++-*+=**@@@*%*###-.      .@@
@@@@@@@@@*     :##@%%%%#%%%++*=*%*****#%*#%***%%*%*%%-**=++-+++-++++-     -** .. :%%%-@*:@**%++++=%*%%#@#%. ...   +@@@@@
@@@@@@@@@@@@*     :#####%#*****=+******%%%#@%%*%*%==++++-+++++++++-+=**%*+ -**%*+#%**+#*+@*%****++%%@#+       :@@@@@@@@@
@@@@@@@@@@@@@@@%     =%@##%%%*+****%**%%%#####%%%+ ::+=+++++++++++=**+: :*%*-%@@:%+-+ #*-%*%*%*%*%*-      .*@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@*     +%#%*%%%****%%%*%###@%%%%*.@#  -***++-=+*+:-   +*%*: ..:--.:= ++=#%%##%*:..    -@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@*    .-@#%*##%****%*#@#%%*%%*.@%-@*: -***-:.-**+%%%%**-:-::-++*% %%*@@*+.      *@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@*     +#@#%%%%**####%%@%#* @#.*%#*++.+%#+%@@*+%*%-.*+--.:-+*%*@#*- .     @@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@:     +@##%#@@%%%%%%%#*.%*=#%*--- -**.: -*=-:++ =-+++.***#- ...   -@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@      *@@#@#@#%*%%%*+@%-***--+ -++:+-..++=+-.*-+=*%#-...    %@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@-     %@@@#@#%*%*+%+-**=--+ *%*----.+--++-%%**: ..   -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+    .%@@#@##%:***+-****.+*****+.:-+=**+ :.   .*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@.    -%@@#%%%%++*****-***+-+=*%%+-::    +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#     -%##%*%**+-=+-***%***+. .    %@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%     -#@%*%*%++*%%#*-:..    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*     +##%*%%#*...    .@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@-    .%#-. .    *@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@-        -#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

-------------------------------------------------- StickyFlow.js----------------------------------------------------------

SFL parser, scene builder, SVG renderer, interactive viewer and editing runtime in one package. No runtime dependencies, no React, no Konva. The static tier is DOM-free and runs in Node.

Install

npm install stickyflow

Node 18 or newer. The package ships ESM, CJS and TypeScript types.

Quick start

import { render } from 'stickyflow'

const { svg, width, height, diagnostics } = render(sfl)
// A complete, deterministic SVG string. render() never touches the DOM.

Five entry points

Import What it is
stickyflow Static tier. SFL text in, SVG string out. Node, SSR, CLI.
stickyflow/viewer Viewer in the DOM: select, hover, pan, zoom, typed events, and live input for components such as a switch or a button.
stickyflow/interaction Editing gestures on a viewer. Reports what changed; the host applies the patch to the SFL text.
stickyflow/binding Data sources, bindings and handlers. createDataSource, createBindingRuntime, renderBound. No DOM.
stickyflow/web-component <stickyflow-diagram> custom element in Shadow DOM, no build step.

Each entry only depends on the ones below it; test/architecture enforces that.

import { createViewer } from 'stickyflow/viewer'
import { bindEditing, applyMoveChange } from 'stickyflow/interaction'

const viewer = createViewer({ container, source: sfl, interactive: true })
const editing = bindEditing(viewer)

editing.on('moveChange', (event) => {
  sfl = applyMoveChange(sfl, event)   // the text changes, nothing else does
  viewer.update({ source: sfl })
})

Components and data binding

A component is an interface element with a value, a look and a behavior. Seven are built in. RollingNumber, TickScale and Ruler show a value. Switch, Checkbox, ToggleButton and Button are operated by the user. An application adds its own type with defineComponent().

A document declares a data source and binds to it. <- makes a property follow the data. <-> also writes the data when the user changes a component value, and onChange runs for each change by the user.

DataSource lamp {
  mode: record
  fields {
    on: boolean
  }
}

Model demo {
  Component power {
    type: switch
    value: <-> lamp.on
    layout {
      position: 0, 0
      size: 104, 60
    }
  }
}
import { createBindingRuntime, createDataSource } from 'stickyflow/binding'
import { connectInteraction, createViewer } from 'stickyflow/viewer'

const viewer = createViewer({ container, source: sfl, interactive: true })
const runtime = createBindingRuntime(sfl)
const lamp = createDataSource({ on: false })

runtime.registerSource('lamp', lamp)
runtime.attach(viewer)
connectInteraction(viewer, runtime)

lamp.set({ on: true })   // the switch follows

Binding and live input need only stickyflow/binding and stickyflow/viewer. Editing with stickyflow/interaction is separate.

What it draws

Shapes, links, frames, swimlanes, screens, paths and text. Fifteen chart types. Isometric objects. A Repeat block puts many alike parts on a grid from a few lines. A Template describes a part once, and a Use sets it again with values of its own. Shader surfaces and components. Data sources with bindings, and events with handlers, so a document can react to data and input.

Principles

  • Deterministic. The same SFL gives the same SVG, byte for byte.
  • Text stays the source. Edits patch the SFL text; comments and order survive.
  • Layered. Language, semantic, render input, scene, SVG, runtime, each with one job and one direction.
src/
  model/         types and registries for shapes, charts, components
  sflLanguage/   AST, lexer, parser, canonical emitter
  sflSemantic/   SFL AST to canvas state
  renderInput/   renderer contract and style decoding
  renderScene/   deterministic scene construction
  svg/           SVG serialization and the DOM contract
  binding/       data sources, bindings and handlers
  runtime/       viewer, interaction, web component

Develop

npm run ci      # lint, typecheck, tests, build, smoke
npm run build   # tsup

How the package and its neighbours fit together: docs/ARCHITECTURE.md. Adding a new placeable object: docs/ADDING_CANVAS_OBJECT.md. Adding a component: docs/ADDING_COMPONENT.md. Changes: CHANGELOG.md.

More

License

Apache-2.0

About

Stickyflow.js is a framework-independent parser, renderer, and editing runtime for using SFL in browsers, Node, and your own applications.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages