{"id":13632609,"url":"https://github.com/munshkr/flok","last_synced_at":"2025-04-07T05:10:39.247Z","repository":{"id":37083008,"uuid":"197101542","full_name":"munshkr/flok","owner":"munshkr","description":"Web-based P2P collaborative editor for live coding sounds and images","archived":false,"fork":false,"pushed_at":"2024-04-09T10:42:09.000Z","size":5194,"stargazers_count":232,"open_issues_count":31,"forks_count":32,"subscribers_count":8,"default_branch":"main","last_synced_at":"2024-04-14T03:03:45.174Z","etag":null,"topics":["codemirror","collaborative-editing","flok","foxdot","hydra","live-coding","livecoding","supercollider","tidalcycles","webrtc"],"latest_commit_sha":null,"homepage":"https://flok.cc","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/munshkr.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null},"funding":{"github":null,"patreon":null,"open_collective":null,"ko_fi":"munshkr","tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2019-07-16T01:55:50.000Z","updated_at":"2024-04-16T10:55:22.317Z","dependencies_parsed_at":"2024-01-19T22:38:51.268Z","dependency_job_id":"3ebd4c6e-f772-4d7c-a6c5-364edbe7367e","html_url":"https://github.com/munshkr/flok","commit_stats":null,"previous_names":[],"tags_count":52,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/munshkr%2Fflok","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/munshkr%2Fflok/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/munshkr%2Fflok/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/munshkr%2Fflok/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/munshkr","download_url":"https://codeload.github.com/munshkr/flok/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247595335,"owners_count":20963943,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["codemirror","collaborative-editing","flok","foxdot","hydra","live-coding","livecoding","supercollider","tidalcycles","webrtc"],"created_at":"2024-08-01T22:03:08.705Z","updated_at":"2025-04-07T05:10:39.240Z","avatar_url":"https://github.com/munshkr.png","language":"TypeScript","readme":"# Flok\n\nWeb-based P2P collaborative editor for live coding music and graphics\n\n## Features\n\n- Similar to Etherpad, but focused on code evaluation for livecoding.\n- Multiple separate slots for different languages and tools.\n- REPL plugins: allows user to locally evaluate code from interpreters (like\n  Haskell, Ruby, Python, etc.):\n  - [TidalCycles](https://tidalcycles.org/)\n  - [SuperCollider](https://supercollider.github.io/) (sclang)\n  - [FoxDot](https://foxdot.org/)\n  - [Renardo](https://renardo.org/)\n  - [Mercury](#mercury)\n  - [Sardine](https://sardine.raphaelforment.fr)\n  - [SonicPi](https://sonic-pi.net/) (_not implemented yet_, see [#29](https://github.com/munshkr/flok/issues/29))\n  - ... any interpreter with a REPL (Python, Ruby, etc.)\n- Web Plugins, for languages embedded in editor:\n  - [Hydra](https://github.com/ojack/hydra)\n  - [p5.js](https://p5js.org/)\n  - [Strudel](https://strudel.cc/)\n  - [Mercury Web](https://www.timohoogland.com/mercury-livecoding/)\n  - [VEDA.js](https://github.com/fand/vedajs) (_not implemented yet_, see [#82](https://github.com/munshkr/flok/pull/82))\n\n## Usage\n\n### Keybindings\n\n*Some keybindings may differ depending on the language/target you choose, and the operating system*\n\n| Keybinding                 | Function                             |\n| -------------------------- | ------------------------------------ |\n| `alt/option` `enter`       | Evaluate all                         |\n| `ctrl/cmd` `enter`         | Evaluate block, Evaluate selection   |\n| `shift` `enter`            | Evaluate line                        |\n| `ctrl/cmd/option/alt` `.`  | Silence (output depends on language) |\n| `cmd/ctrl` `shift/alt` `h` | Show/Hide editor panels              |\n| `cmd/ctrl` `x`             | Cut selected text                    |\n| `cmd/ctrl` `c`             | Copy selected text                   |\n| `cmd/ctrl` `v`             | Paste cut/copied text                |\n| `cmd/ctrl` `z/u`           | Undo edit                            |\n| `cmd/ctrl` `shift` `z/u`   | Redo edit                            |\n| `cmd/ctrl` `}`             | add indentation                      |\n| `cmd/ctrl` `{`             | remove indentation                   |\n| `cmd/ctrl` `f`             | search and replace                   |\n\n*On Mac:*\n\n| `ctrl` `e` | jump to end of the line |\n| `ctrl` `a` | jump to the beginning of the line |\n| `ctrl` `t` | move character one step right |\n| `ctrl` `y` | delete selected text |\n| `ctrl` `o` | insert linebreak |\n| `ctrl` `d` | delete character on the right of cursor |\n| `ctrl` `h` | backspace character on the left of cursor |\n| `ctrl` `l` | select whole line after cursor |\n| `ctrl` `v` | jump to bottom end |\n| `ctrl` `b` | move cursor to the left |\n| `ctrl` `n` | move cursor down |\n\n### Public server\n\n**WARNING - Please Read**: Using a public server can be dangerous as _anyone_\ncan execute code on your computer via Flok, so _please_ make sure you only\nshare your session URL to trusted users and friends when you use a public\nserver. I will not be held responsible for any damaged caused by Flok. You\nhave been warned.\n\nThis is a list of known public servers:\n\n- [flok.cc](https://flok.cc)\n\n#### Create a session\n\nWhen you enter a Flok server, you will be shown an empty session with a single\nslot, with a _target_ selected (usually `hydra`). You can either change the\ntarget by clicking on the target selector at the top-left corner of the slot, or\nadd more slots by clicking on the _Command button_ (at the top-right corner of the\nscreen), and then clicking on _Add Pane_, or _Configure_.\n\nA _target_ is the language or tool that Flok will communicate to create sound or\nimages within the web page, or through `flok-repl`.\n\nIf you clicked on _Configure_, enter the name of the targets, separated with\ncommas. You can use a target multiple times and Flok will create that many\nnumber of slots to write code. Currently the maximum number of slots is 8.\n\nExamples:\n\n- `tidal, foxdot, hydra`: 3 slots, with tidal, foxdot and hydra respectively.\n- `sclang, sclang, sclang, hydra, hydra`: 5 slots total, the first 3 with\n  `sclang` and the last 2 with `hydra`.\n- `mercury, hydra`: 2 slots total, one with Mercury and one with Hydra.\n\nYou will also be asked to enter a nickname. This is the name that will be shown\nto other users under your cursor, when you write code. You can change it any\ntime by clicking on the _Change Username_ inside the _Command_ menu.\n\nNow, just copy the URL and share it with your friends! They will be able to\njoin the session and write code with you :-)\n\nIf you are using any target that requires a REPL, you will need to start it\nseparately. See the _Connect REPLs to Flok_ section below.\n\n#### Connect REPLs to Flok\n\nThe last step is to start `flok-repl`, to connect Flok with your REPLs.\n\nJust click on the _REPLs_ button at the top-right corner of the screen, and\ncopy the command shown there. It will look something like this:\n\n```sh\nnpx flok-repl@latest -H wss://next.flok.cc \\\n  -s mammoth-tan-roundworm-17a5d501 \\\n  -t tidal \\\n  -T user:munshkr\n```\n\nThis command will automatically try to download and install `flok-repl` and\nstart it, connecting it to your session. If you have multiple different targets\nwith REPLs, the command will start one process for each target from the same\ncommand.\n\n### Local server\n\nIn case you want to use Flok without Internet connection and/or you don't want\nto play Flok on a public server, you can easily start a local Flok server.\n\nTo start the server, simply run:\n\n```sh\nnpx flok-web@latest\n```\n\nYou can also install both `web` and `repl` packages beforehand (e.g. if you\nalready know you won't have internet access on the venue) with:\n\n```sh\nnpm install -g flok-web@latest flok-repl@latest\n```\n\nThis will download and install the latest Flok web version and start a server.\n\nYour local server will be available on\n[http://localhost:3000](http://localhost:3000) from your computer. To share the\nURL with your friends, change `localhost` with your local LAN IP. `flok-web`\nwill try to guess your local IP in your LAN, and show it on the console, but it\nmight not always work.\n\n#### Secure mode (https)\n\nIn some cases, it's needed to run Flok in secure mode, using https. This is\nneeded for some browsers, like Chrome, to allow access to the microphone and\ncamera (which might be needed for some targets, like Hydra). You can easily\nrun Flok in secure mode by passing the `--secure` parameter:\n\n```sh\nnpx flok-web@latest --secure\n```\n\n#### Note about remote users (not LAN)\n\nSharing your local server to other users in the Internet is a bit more\ncomplicated, and it depends on your router and network configuration. You will\nneed to configure your router to forward the port 3000 to your computer, and\nthen share your public IP with your friends. You can find your public IP by\nvisiting [https://whatismyipaddress.com/](https://whatismyipaddress.com/). Also\nmake sure to check your firewall settings, to allow incoming connections to\nport 3000. It's possible that some of your remote friends won't be able to\nconnect to your local server, because of their own network configuration.\n\n### Supported REPL targets\n\n#### Dummy\n\nThe \"dummy\" target is a REPL target that forwards messages to an OSC server. It\ndoes not have any syntax highlighting and can be used for any purpose you like.\nThis is useful if you want to use a language that is not yet supported in Flok,\nand can receive OSC messages.\n\nUse `flok-repl` with the `-t dummy` parameter. \n\nBy default, it will send OSC messages to port 3001. Code evaluations are sent as\na string (including all line breaks, whitespaces, etc.) to the OSC address\n`/flok`. If you use the `panic` shortcut key, you will receive the OSC message\n`/flok silence`, which you can use to stop all your audio/visual processes.\n\n#### TidalCycles\n\nUse `flok-repl` with the `-t tidal` parameter.\n\nYou can specify custom options with the `--extra` parameter, by passing a JSON\nobject, like this:\n\n`--extra '{ \"bootScript\": \"/path/to/my/boot.hs\", \"useStack\": true }'`\n\n##### Extra options\n\n- `bootScript`: Path to a custom initialization script.\n\n- `useStack`: Uses `stack exec -- ghci` instead of plain `ghci`. Use this if\n  you installed Tidal using Stack.\n\n- `ghci`: Use a specific Ghci command instead of plain `ghci`.\n  This overrides `useStack` option, if used too.\n\n#### Sardine\n\nUse `flok-repl` with the `-t sardine` parameter. In order to make it work,\nthe `sardine` REPL must be included to your PATH. It should already be the\ncase if you followed a regular install.\n\n##### Extra options\n\n- `python`: Path to your custom `sardine` Python REPL. Use this if you need\n  to target a specific install of Sardine (Python version, different path, etc).\n\n#### FoxDot\n\nUse `flok-repl` with the `-t foxdot` parameter.\n\n##### Extra options\n\n- `python`: Path to Python binary. Use this if you need to use a custom Python\n  version.\n\n#### Renardo\n\n[Renardo](https://renardo.org) is a new maintained fork of FoxDot with new features.\n\nUse `flok-repl` with the `-t renardo` parameter.\n\n##### Extra options\n\n- `python`: Path to Python binary. Use this if you need to use a custom Python\n  version.\n\n#### SuperCollider\n\nIn the case of SuperCollider, there are two types of REPLs: `sclang` and\n`remote_sclang`. The first one tries to run a `sclang` process and interact\nwith it, while the second one uses\n[FlokQuark](https://github.com/munshkr/FlokQuark) to communicate with SC. Read\n[more](https://github.com/munshkr/FlokQuark/blob/master/README.md) for\ninstalling and using it.\n\n##### `sclang` vs. `remote_sclang`\n\n- As of today `sclang` does not currently work on Windows, you will have to use\n  `remote_sclang`.\n\n- `remote_sclang` needs SC IDE to be running, and you need FlokQuark installed\n  and running there. Be sure to start your flok-repl with both `-t remote_sclang`\n  and `-n sclang` flags.\n\n- If you use `remote_sclang`, you won't see Post messages from Flok, because\n  FlokQuark does not currently capture Post messages and errors. It is\n  recommended to deattach the Post window and have it visible while using Flok.\n\n- `sclang` can't use any GUI object (like Scopes, Proxy mixers, etc.). You will\n  need to use `remote_sclang` + SC IDE for this.\n\n#### Hydra\n\n[Hydra](https://hydra.ojack.xyz/) is a video synth and coding environment, inspired in\nanalog video synthesis, that runs directly in the browser and is already included in\nthe web App. You don't need to install anything as it runs on the browser. Just use\nthe `hydra` target to execute Hydra code.\n\nYou can also use [p5.js](https://p5js.org/) within a `hydra` target, like you would in\nthe official Hydra editor.\n\n##### `P()` function\n\nThe `P()` function allows you to use strudel mini-patterns in Hydra.\nIt uses the same timing information as Strudel itself, so it will be synchronized with the audio.\n\n**Note**: It will only work, if strudel is already initialized, because that will load the modules we need.\n**Note**: You can not use any strudel functions on the pattern.\n**Note**: Currently we do not have mini-highlighting for Hydra panes.\n\n##### `useStrudelCanvas(source)`\n\nWill initialise the given source (`s0`, `s1`, etc) to use the strudel canvas as a source.\nWill also hide the strudel canvas, so it will not overlap.\n\n**Note**: Strudel will have to be initialized, otherwise this will not work.\n\n##### `fft()` function\n\nThe `fft()` function is a special function that allows you to get the FFT data\nfrom web targets.\n\n**Note: Only Strudel is supported at the moment.**\n\n**You can disable the FFT visualizer in the display settings. This might help with performance.**\n\n```ts\nfft(index: number,\n    buckets: number = 8,\n    options?: { min?: number; max?: number, scale?: number, analyzerId?: string }): number\n```\n\nParameters:\n\n- `index: number` (default: 0): The index of the bucket to return the value from.\n- `buckets: number` (default:1): The number of buckets to combine the underlying FFT data\n  too. Defaults to 8.\n- `options?: { min?: number; max?: number, scale?: number } | string`:\n  - if string, it sets the `analyzerId` option directly\n  - `min?: number`: Minimum clamp value of the underlying data. Defaults to\n    -150.\n  - `max?: number`: Maximum clamp value of the underlying data. Defaults to 0.\n  - `scale?: number`: Scale of the output. Defaults to 1 (so the output is\n    from 0 to 1)\n  - `analyzerId?: string`: Which Strudel analyser to listen to. Defaults to\n    `flok-master`, which is also automatically added to all strudel patterns.\n    Can be used to route different patterns to different parts of the hydra\n    visualiser\n\nExample:\n\n```js\nsolid(() =\u003e fft(0, 1), 0)\n  .mask(shape(5, 0.05))\n  .rotate(() =\u003e 50 * fft(0, 40)); // we need to supply a function\n// for the parameter, for it to update automaticaly.\n```\n\n**Caveat**: Because of how we setup the analyze node on Strudel, every Strudel pane\nneeds a re-eval after the Hydra code decides that we need to get the fft data.\nThis does not happen automatically, manual re-eval is necessary.\n\n#### Mercury\n\n[Mercury](https://github.com/tmhglnd/mercury) is a minimal and human readable\nlanguage for livecoding of algorithmic electronic music. Below is a link to steps for\nconnecting Flok to either the Mercury Playground (browser based) or the Max8 version\nof the livecoding environment:\n\n[Follow the step-by-step guide here](https://tmhglnd.github.io/mercury/collaborate.html)\n\nBug reports are welcome in the issues. If the issue is more Mercury than Flok related please\nreport [here](https://github.com/tmhglnd/mercury/issues/new)\n\n## Development\n\n### Basic setup\n\nInstall all dependencies and build all subpackages with:\n\n```sh\nnpm install\nnpm run build\n```\n\nThen, to run web server:\n\n```sh\ncd packages/web\nnpm run dev\n```\n\nTo run production build:\n\n```sh\nnpm start\n```\n\nTo run the repl while developing go to:\n\n```sh\ncd packages/repl/\n```\n\n```sh\nnpm exec -- flok-repl -H ws://localhost:3000 -s \u003csession\u003e -t \u003ctarget\u003e -T user:\u003cname\u003e\n```\n\n### Packages overview\n\nThis repository is a monorepo, with multiple modular packages. Each package\nhas its own README with more information. Here is a brief overview of the\npackages:\n\n#### App packages\n\n- [`flok-web`](packages/web): Web Server for Flok\n- [`flok-repl`](packages/repl): REPL Client for Flok\n- [`flok-server`](packages/server): Flok server, handles sessions and\n  communication between clients.\n\n#### Lib packages\n\n- [`@flok-editor/pubsub`](packages/pubsub): Pub/Sub client-server, used for\n  remote code execution and message passing on Flok\n- [`@flok-editor/session`](packages/session): Flok session package\n- [`@flok-editor/server-middleware`](packages/server-middleware): Server\n  middleware for Flok, handles WebSocket connections and WebRTC signaling\n- [`@flok-editor/cm-eval`](packages/cm-eval): CodeMirror 6 extension for code\n  evaluation\n- [`@flok-editor/lang-tidal`](packages/lang-tidal): TidalCycles language support\n  for CodeMirror 6\n\n#### Examples\n\n- [`example-vanilla-js`](packages/example-vanilla-js): Example of a Flok-based\n  collaborative editor written in pure JS and Vite\n\n### Design constraints (v1.0)\n\n- Include a simplified vanilla JS example\n- Use [CodeMirror 6](https://codemirror.net/)\n  - Best code editor library for the Web\n  - Latest version (v6) comes with better extensibility and accesability\n- Use [Yjs](https://yjs.dev/) for collaborative editor\n  - Battle-tested and updated\n  - Now supports CodeMirror 6:\n    [y-codemirror.next](https://github.com/yjs/y-codemirror.next)\n- More modular and extensible, similar to CodeMirror extensions, e.g.:\n  - Line/block-based evaluation: `@flok-editor/cm-eval`\n  - TidalCycles pattern and RMS decorators: `@flok-editor/cm-tidalcycles-decorators`\n  - TidalCycles autocompletion: `@flok-editor/cm-tidalcycles-autocompletion`\n  - Hydra synth autocompletion: `@flok-editor/cm-hydra-autocompletion`\n- Better UI for customizing editor and session configuration\n  - Menu, toast, dialogs\n- _nice to have_ Import external JS libraries dynamically, instead of bundling\n  them with Flok\n  - Similar to JS playgrounds, like [codesandbox.io](https://codesandbox.io/)\n  - User can have their own set of libraries to be loaded automatically or\n    easily on new sketches\n  - Connect to local filesystem for files and libraries\n\n### Hash parameters\n\n- `username` (string): Default user name. Eg: `#username=arbor`\n- `targets` (list of strings): If session is empty, configure it with the\n  specified targets by default. Eg: `#targets=hydra,strudel`\n- `c0`, `c1`, ..., `c7` (string): Default code to load on each document/pane\n  (if available). **Code must be encoded in Base64**. Eg:\n  `#c0=bm9pc2UoKS5vdXQoKQ%253D%253D` (decodes to `noise().out()`).\n- `code` (string): An alias of `c0` (see above)\n\n### Query parameters\n\n- `readOnly` (boolean): Disable editing. If true, it won't ask for a user name\n  when loading.\n- `bgOpacity` (number): Background opacity. Valid range: [0, 1]\n- `noWebEval` (list of strings): Disable evaluation of the specified web\n  targets. Useful for embedding Flok in a website, where the website already has\n  its own evaluation mechanism. This still sends messages to parent window.\n  Options: `*`, `[webTarget]`. Eg: `?noWebEval=hydra` disables only Hydra.\n  `?noWebEval=*` disables all web targets.\n- `hideErrors` (boolean): Do not show errors for web targets (hydra, strudel, etc)\n\n### Window messages\n\nFlok will post messages to the parent window on specific events. This is useful\nfor embedding Flok in a website, where the website can handle the evaluation of\nthe code.\n\n#### Events\n\n- `change`: When the session changes. This usually happens at the beginning,\n  when the session is empty, and when the user changes the targets.\n\n```json\n{\n  \"event\": \"change\",\n  \"documents\": [\n    {\n      \"id\": \"1\",\n      \"target\": \"hydra\",\n      \"content\": \"osc().out()\"\n    },\n    {\n      \"id\": \"2\",\n      \"target\": \"tidal\",\n      \"content\": \"d1 $ s \\\"bd\\\"\"\n    }\n  ]\n}\n```\n\n- `eval`: On evaluation. This happens when the user presses the \"Run\" button or\n  when the user presses one of the shortcuts for evaluating (e.g. `Ctrl+Enter`)\n  on the editor. Only the content of the document that was evaluated is sent.\n\n```json\n{\n  \"event\": \"eval\",\n  \"id\": \"2\",\n  \"content\": \"d1 silence\",\n  \"user\": \"munshkr\"\n}\n```\n\n## Acknowledgments\n\n- [Etherpad](https://github.com/ether/etherpad-lite)\n- [Troop](https://github.com/Qirky/Troop)\n- [TidalBridge](https://gitlab.com/colectivo-de-livecoders/tidal-bridge)\n\n## Contributing\n\nBug reports and pull requests are welcome on GitHub at the [issues\npage](https://github.com/munshkr/flok). This project is intended to be a safe,\nwelcoming space for collaboration, and contributors are expected to adhere to\nthe [Contributor Covenant](http://contributor-covenant.org) code of conduct.\n\n## License\n\nThis project is licensed under GPL 3+. Refer to [LICENSE.txt](LICENSE.txt).\n\nPunctual is licensed under GPL 3+. Refer to \n[LICENSE](https://github.com/dktr0/Punctual/blob/main/LICENSE).\n\nFavicon based on \"Origami\" by Andrejs Kirma, from [Noun\nProject](https://thenounproject.com/browse/icons/term/origami/) (CC BY 3.0)\n","funding_links":["https://ko-fi.com/munshkr"],"categories":["TypeScript","Projects"],"sub_categories":["Tool"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmunshkr%2Fflok","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmunshkr%2Fflok","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmunshkr%2Fflok/lists"}