docs(falinks): add public surfaces note
This commit is contained in:
193
docs/02 notes/falinks public surfaces.md
Normal file
193
docs/02 notes/falinks public surfaces.md
Normal file
@@ -0,0 +1,193 @@
|
||||
---
|
||||
date-created: 2026-08-31 21:32
|
||||
---
|
||||
|
||||
# Falinks Public Surfaces
|
||||
|
||||
The project has three components:
|
||||
- `Falinks`: the library to resolve short links to fully qualified domain names.
|
||||
- `falinks` cli:
|
||||
- Non-interactive (use for one off requests or by agents)
|
||||
- Interactive mode (REPL-style)
|
||||
- Daemon: running in the background, can be used through unix domain sockets (or another inter-process communication)
|
||||
- Web server: serves browser requests, including the special `/` management page and 404 page.
|
||||
|
||||
The `falinks` CLI should have very light logic (if any) related to short links.
|
||||
It should be focused on being the front end(s) that uses the library.
|
||||
|
||||
`falinks` will use [[machoke]] for the storage layer.
|
||||
|
||||
## Design
|
||||
|
||||
### `Falinks` public interface
|
||||
|
||||
| Method | Parameters | Returns | Description |
|
||||
| --------------- | --------------------------------- | ----------------------------- | ------------------------------------------------------- |
|
||||
| `<constructor>` | `falinks::Options` | `Falinks` | Creates the stateful object. See [[falinks public surfaces#falinks::Options]] |
|
||||
| `get` | `short_link: String` | `Result<String>` | Returns the `url` stored for `short_link` if it exists. |
|
||||
| `set` | `short_link: String, url: String` | `Result<()>` | Stores `url` with `short_link` key. |
|
||||
| `delete` | `short_link: String` | `Result<bool>` | Deletes the entry for `<short_link>`. |
|
||||
| `list` | | `Result<Vec<falinks::Entry>>` | Retrieves all stored, raw values. |
|
||||
|
||||
|
||||
#### falinks::Options
|
||||
|
||||
| Key | Type | Default | Description |
|
||||
| ------------- | ---------------------- | ------- | ------------------------------------------------------------------------------ |
|
||||
| `socket_path` | `std::path::PathBuf` | | The path for the Unix Domain Socket. Implicitly starts the daemon. |
|
||||
| `listen_addr` | `std::net::SocketAddr` | | The address for the web server to listen on. Implicitly starts the web server. |
|
||||
| `store` | `std::path::PathBuf` | tbd | The path to read/write the store. Passed to [[machoke]]. |
|
||||
|
||||
|
||||
#### falinks::Error
|
||||
|
||||
- `NotFound`: no entry exists for the provided `<prefix>/<short_link>`.
|
||||
- `InvalidShortLink`: the provided short link could not be resolved.
|
||||
- `InvalidUrl`: the target URL is not valid.
|
||||
- `Store`: [[machoke]] failed while reading or writing the store. Maybe treat this as an "external" error?
|
||||
|
||||
#### falinks::Entry
|
||||
|
||||
| Field | Type | Description |
|
||||
| -------------- | -------- | -------------------------------------------------------------------------------------------- |
|
||||
| `prefix` | `String` | The namespace for the short link. |
|
||||
| `short_link` | `String` | The short link key. It can contain `/`. |
|
||||
| `url` | `String` | The target URL. |
|
||||
| `visit_count` | `u64` | Successful `get` operations increment `visit_count`. |
|
||||
| `last_used` | `u64` | Unix timestamp in seconds. Successful `get` operations update `last_used`. |
|
||||
| `last_updated` | `u64` | Unix timestamp in seconds of when the entry was last updated. Metadata updates do not count. |
|
||||
|
||||
|
||||
### `falinks` CLI
|
||||
|
||||
| Command | Description |
|
||||
| -------------------------------------- | ------------------------------------------------------------------------------------- |
|
||||
| `falinks` | Launches `falinks` interactive mode. |
|
||||
| `falinks list` | Will return all stored URLs and keys, along with metadata like visit count. |
|
||||
| `falinks get <short_link>` | Resolve the short link into a URL. See [[falinks public surfaces#Resolving short links]]. |
|
||||
| `falinks set <short_link> <url>` | Store the `<url>` with `<short_link>` key. `<short_link>` still needs to be resolved. |
|
||||
| `falinks delete <short_link>` | Delete the entry that matches `<short_link>`. |
|
||||
| `falinks start [--config-path <path>]` | Starts the daemon, web server or both as configured. See [[falinks public surfaces#falinks::Options]]. |
|
||||
| `falinks stop` | Stops the running daemon. |
|
||||
|
||||
#### Global Flags
|
||||
|
||||
| Flag | Description |
|
||||
| ----------- | --------------------------------------------- |
|
||||
| `--help` | Prints the help text. |
|
||||
| `--version` | Prints version information. |
|
||||
| `--json` | Turns all output and errors machine-readable. |
|
||||
|
||||
|
||||
#### JSON payloads
|
||||
|
||||
All JSON command responses must include `ok`.
|
||||
`--json` does not affect `--help` or `--version`.
|
||||
|
||||
> [!info] Successful List
|
||||
> ```json
|
||||
> {
|
||||
> "ok": true,
|
||||
> "entries": [
|
||||
> {
|
||||
> "prefix": "fa",
|
||||
> "short_link": "home/plex",
|
||||
> "url": "https://plex.example.com",
|
||||
> "visit_count": 12,
|
||||
> "last_used": 1788210000,
|
||||
> "last_updated": 1788200000
|
||||
> }
|
||||
> ]
|
||||
> }
|
||||
> ```
|
||||
|
||||
> [!info] Successful `get`
|
||||
> ```json
|
||||
> {
|
||||
> "ok": true,
|
||||
> "url": "https://example.com"
|
||||
> }
|
||||
> ```
|
||||
|
||||
> [!info] Successful `set`
|
||||
> ```json
|
||||
> {
|
||||
> "ok": true
|
||||
> }
|
||||
> ```
|
||||
|
||||
> [!info] Successful `delete`
|
||||
> ```json
|
||||
> {
|
||||
> "ok": true,
|
||||
> "deleted": true
|
||||
> }
|
||||
> ```
|
||||
|
||||
> [!info] Successful `start`
|
||||
> ```json
|
||||
> {
|
||||
> "ok": true,
|
||||
> "pid": 1234
|
||||
> }
|
||||
> ```
|
||||
|
||||
> [!info] Successful `stop`
|
||||
> ```json
|
||||
> {
|
||||
> "ok": true
|
||||
> }
|
||||
> ```
|
||||
|
||||
> [!info] Error response
|
||||
> ```json
|
||||
> {
|
||||
> "ok": false,
|
||||
> "error": {
|
||||
> "code": "not_found",
|
||||
> "message": "no entry exists for fa/home/plex"
|
||||
> }
|
||||
> }
|
||||
> ```
|
||||
|
||||
See [[falinks public surfaces#falinks::Error]] for more details on the variants.
|
||||
|
||||
### `falinks` daemon IPC
|
||||
|
||||
Daemon IPC uses newline-delimited JSON over the Unix Domain Socket.
|
||||
Each request and response is one JSON object followed by a newline.
|
||||
|
||||
Requests mirror the CLI commands:
|
||||
|
||||
```json
|
||||
{"command":"get","short_link":"fa/home/plex"}
|
||||
{"command":"set","short_link":"fa/home/plex","url":"https://plex.example.com"}
|
||||
{"command":"delete","short_link":"fa/home/plex"}
|
||||
{"command":"list"}
|
||||
{"command":"stop"}
|
||||
```
|
||||
|
||||
Responses use the same payload shapes as `falinks --json`.
|
||||
See [[falinks public surfaces#JSON payloads]].
|
||||
|
||||
### `falinks` web server
|
||||
|
||||
| Request | Return Code | | Description |
|
||||
| --------------------------------------------------- | ----------- | ----------------- | ------------------------------------------------------------------------------ |
|
||||
| `GET <prefix>/` | `200` | Falinks Dashboard | The web dashboard to manage `falinks`. All prefixes return the same dashboard. |
|
||||
| `GET <prefix>/<short_link>` | `307` | `<url>` | Returns a temporary redirect to the stored `<url>` |
|
||||
| | `404` | 404 Page | If the `<prefix>/<short_link>` entry was not found. |
|
||||
| `POST <prefix>/<short_link> body: {"url": "<url>"}` | `201` | | Creates the `<prefix>/<short_link>` entry for `<url>` |
|
||||
| `DELETE <prefix>/<short_link>` | `200` | | Deletes the `<prefix>/<short_link>` entry. |
|
||||
| | `204` | | No entry found for `<prefix>/<short_link>` |
|
||||
|
||||
|
||||
|
||||
### Resolving short links
|
||||
|
||||
`[{http | https}://]<prefix>/<short_link>`
|
||||
|
||||
- The presence of either `http://` or `https://` indicates this short link should be resolved through the machine's DNS. Otherwise, it will be resolved through the daemon on the machine.
|
||||
- `<prefix>` can technically be anything, the library will support that. But I will only use `go` or `fa` (to be decided). Prefixes do not share keys.
|
||||
- `<short_link>` can be nested (`home/plex`), although it has no semantic meaning.
|
||||
|
||||
Reference in New Issue
Block a user