diff --git a/README.md b/README.md index d46899f7..c6025f41 100644 --- a/README.md +++ b/README.md @@ -50,8 +50,8 @@ updates to any changes as you are typing and the scrolling is smoothly synchronized! See below for a list of existing editor plugins. In case your favorite editor is -not yet supported, use these as an example to write your own and add it to the -list! +not yet supported, use these as an example to write your own or check out the +[API documentation](docs/api.md) and add it to the list! #### Existing integration diff --git a/docs/api.md b/docs/api.md new file mode 100644 index 00000000..60ba885a --- /dev/null +++ b/docs/api.md @@ -0,0 +1,71 @@ +# Vivify's API + +In addition to the command line interface `viv`, Vivify has HTTP endpoints that +are be used to integrate it into other applications, such as making editor +plugins for live previews. + +## Path encoding + +Vivify's endpoints are often accessed with the pattern `//` +where path is a +[percent-encoded](https://developer.mozilla.org/en-US/docs/Glossary/Percent-encoding) +path in the file system. For paths that follow UNIX naming conventions, this +means that endpoints are be accessed directly at the literal paths. For example, +accessing `` for a file at `/Users/me/my-file.md` is done through the +URL. + +```txt +//Users/me/my-file.md +``` + +For paths that have special characters such as spaces, use +[percent-encoding](https://developer.mozilla.org/en-US/docs/Glossary/Percent-encoding). +E.g. to access `` for a file at `Users/me/my file.md`, it will be the +following. + +```txt +//Users/me/my%20file.md +``` + +## Endpoints + +Vivify has two routes of endpoints, `/health`, and `/viewer`. + +### `/health` + +This endpoint is used for checking the status of Vivify Server and its clients +(connected viewers). Sending a `GET` request directly to `/health` will reply +with status 200 if Vivify Server is running. Sending a `GET` request to +`/health/` (as defined in [Path encoding](#path-encoding)) will reply with +status 200 if there are clients connected at the given path, or with 404 if +there aren't. + +### `/viewer` + +This endpoint is used to manipulate connected clients. + +Sending a `POST` to `/viewer/` (as defined in [Path +encoding](#path-encoding)) will always reply with the following response. + +```typescript +{ + "clients": number // number of clients connected at +} +``` + +The request can include a body with the following optional fields. + +```typescript +{ + "content": string, // Live update the entire file's content to the given + // value. + "cursor": number, // For markdown files, scroll all viewers to the content + // corresponding to the given line in the source file. + "reload": boolean // Live update the viewer based on the current content + // on disk. Note that this overrides "content". +} +``` + +Sending a `DELETE` request to `/viewer` will fully reload all connected clients +at any paths and clear all cached updated live content. Sending a `DELETE` +request to `/viewer/` will do the same for all clients at the given path. diff --git a/docs/architecture.md b/docs/architecture.md new file mode 100644 index 00000000..6ed45229 --- /dev/null +++ b/docs/architecture.md @@ -0,0 +1,54 @@ +# Architecture overview + +intro text + +## Scope of this repository + +This repo includes just main Vivify which aims to be very configurable and +easily integrable. Everything else (e.g. vivify.vim) are their own projects with +their own repos + +## Executables + +we have two executables: `viv` and `vivify-server`: + +- `viv` is just a small wrapper that + 1. runs Vivify Server + 2. forwards everything Vivify Server prints to `stdout` to its own `stdout` + until the server prints `STARTUP COMPLETE` + 3. disowns the server process so it keeps running in the background while + `viv` can terminate +- `vivify-server` is the actual Node.js app that does almost everything and is + described in the rest of this doc + +## Vivify Server overview + +- (focus on `src/app.ts`) When `vivify-server` is called, there are two + scenarios which we distinguish through the [`/health` endpoint](docs/api.md): + 1. There is already another instance of Vivify Server running: We have to + reuse that instance and have it open the requested viewer. + 2. There is no other instance running: We have to start the server and + then handle the requests ourselves. +- Vivify Server is + 1. an [Express](http://expressjs.com) server that serves the + [API](docs/api.md) and the viewers + 2. (focus on `src/sockets.ts`) a WebSocket server that keeps 1 socket + connection with each client (viewer browser tab) to + 1. be able to manipulate clients, e.g. for editor integration + 2. know when there are no clients left so we can shut down Vivify Server +- rendering files happens in the `src/parser` directory + - for Markdown we use [markdown-it](https://www.npmjs.com/package/markdown-it) + and most Markdown features can be handled with plugins from there + - Notebook rendering is implemented from scratch but by heavily relying on the + existing ability render Markdown + +## Build infrastructure overview + +- we use [Node SEA](https://nodejs.org/api/single-executable-applications.html) + which is still in beta to compile Vivify Server into a single executable + without needing a Node dependency +- this is why we can't simply use native Express static router but had to come + up with a custom solution in `src/routes/static.ts`: + - at development time, we just serve whatever is in the `static/` directory + - at production time we access all contents of the `static/` directory through + an archive that is included as an asset in the SEA