diff --git a/docs/02 notes/falinks public surfaces.md b/docs/02 notes/falinks public surfaces.md new file mode 100644 index 0000000..94b2be9 --- /dev/null +++ b/docs/02 notes/falinks public surfaces.md @@ -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 | +| --------------- | --------------------------------- | ----------------------------- | ------------------------------------------------------- | +| `` | `falinks::Options` | `Falinks` | Creates the stateful object. See [[falinks public surfaces#falinks::Options]] | +| `get` | `short_link: String` | `Result` | 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` | Deletes the entry for ``. | +| `list` | | `Result>` | 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 `/`. +- `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 ` | Resolve the short link into a URL. See [[falinks public surfaces#Resolving short links]]. | +| `falinks set ` | Store the `` with `` key. `` still needs to be resolved. | +| `falinks delete ` | Delete the entry that matches ``. | +| `falinks start [--config-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 /` | `200` | Falinks Dashboard | The web dashboard to manage `falinks`. All prefixes return the same dashboard. | +| `GET /` | `307` | `` | Returns a temporary redirect to the stored `` | +| | `404` | 404 Page | If the `/` entry was not found. | +| `POST / body: {"url": ""}` | `201` | | Creates the `/` entry for `` | +| `DELETE /` | `200` | | Deletes the `/` entry. | +| | `204` | | No entry found for `/` | + + + +### Resolving short links + +`[{http | https}://]/` + +- 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. +- `` 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. +- `` can be nested (`home/plex`), although it has no semantic meaning. + diff --git a/docs/03 wrk/falinks.md b/docs/03 wrk/falinks.md new file mode 100644 index 0000000..2c545c1 --- /dev/null +++ b/docs/03 wrk/falinks.md @@ -0,0 +1,14 @@ +--- +date-created: 2026-08-31 21:32 +--- + +# Falinks + +## Current focus + +Design the [[machoke]] public surfaces. + +## References + +- [[falinks public surfaces]] +- [[machoke]]