{"id":13755910,"url":"https://github.com/ostcar/kingfisher","last_synced_at":"2026-01-22T12:46:55.351Z","repository":{"id":230945788,"uuid":"779203583","full_name":"ostcar/kingfisher","owner":"ostcar","description":null,"archived":false,"fork":false,"pushed_at":"2025-02-15T09:24:44.000Z","size":96,"stargazers_count":20,"open_issues_count":1,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-05-10T03:31:36.311Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Roc","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ostcar.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-03-29T09:23:13.000Z","updated_at":"2025-04-25T22:18:06.000Z","dependencies_parsed_at":"2024-04-28T15:26:12.370Z","dependency_job_id":"0da32b66-0217-42e3-99a6-c3494806fafa","html_url":"https://github.com/ostcar/kingfisher","commit_stats":null,"previous_names":["ostcar/kingfisher"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/ostcar/kingfisher","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ostcar%2Fkingfisher","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ostcar%2Fkingfisher/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ostcar%2Fkingfisher/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ostcar%2Fkingfisher/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ostcar","download_url":"https://codeload.github.com/ostcar/kingfisher/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ostcar%2Fkingfisher/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28663211,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-22T01:17:37.254Z","status":"online","status_checked_at":"2026-01-22T02:00:07.137Z","response_time":144,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2024-08-03T11:00:32.612Z","updated_at":"2026-01-22T12:46:55.335Z","avatar_url":"https://github.com/ostcar.png","language":"Roc","funding_links":[],"categories":["Roc Platforms 🏢","Projects"],"sub_categories":[],"readme":"# Kingfisher\n\nKingfisher is a webserver platform for the [Roc\nlanguage](https://www.roc-lang.org/).\n\nIt lets you build websites by defining your own Model. The model is held in\nmemory. No need for SQL.Changes to the model are saved to disk in an event store.\n\n\n## Current state of the project\n\nThe project is in an early stage. I am currently exploring the API. There will\nbe many breaking changes. There will probably also be changes, how the data is\nstored on disk, without the possibility to migrate the data.\n\nPlease inform me, if you plan to use this platform, so I can keep your use case\nin mind and consider writing migrations.\n\n\n## How to use it\n\nUse the platform with the following roc-application-header:\n\n```roc\napp [init_model, update_model, handle_request!, Model] {\n    webserver: platform \"https://github.com/ostcar/kingfisher/releases/download/v0.0.6/CGvtit0XrLnoN00TVk3Ggseg8nXTe9UykuX7dAcETmw.tar.br\",\n}\n```\n\nThe platform requires a `Model`. The `Model` can be any valid roc type. For\nexample:\n\n```roc\nModel : {\n    modelVersion: U64,\n    users: List User,\n    admin: [NoAdmin, Admin Str],\n    books: List Str,\n    specialOption: Bool,\n}\n```\n\nThe platform needs three functions:\n\n```roc\ninit_model: Model\nupdate_model : Model, List (List U8) -\u003e Result Model _\nhandle_request! : Http.Request, Model =\u003e Result Http.Response _\n```\n\n* **init_model**: `init_model` has to return the first version of the model. Be\ncareful, when changing this. Your events need to be compatible.\n\n* **update_model**: `update_model` runs the events. Be careful, when changing\nthe implementation. Old events can not be migrated.\n\n* **handle_request!**: `handle_request!` is called for each HTTP requests.\nThe function is called with the `Request` and the `Model` and has to return\na `Result Response _`.\n\n* **save_event!**: To change the model, you have to pattern match on the request\nmethod. Write requests (`POST`, `PUT`, `PATCH` and `DELETE`) have an function as\npayload this function can be used to save an event.\n\n```roc\nwhen request.method is\n    Get -\u003e\n        ...\n\n    Post save_event! -\u003e\n        save_event!(my_event)\n```\n\nAn event is a `List U8`. Make sure to implement `update_model` to handle all of\nyour events.\n\nThe platform makes the distinction between a read and a write request on the\nHTTP method. `POST`, `PUT`, `PATCH` and `DELETE` requests are write requests.\nAll other methods are read requests. This means, that a `GET` request can not\nalter the Model.\n\nThe platform can handle many read requests at the same time. But there can only\nbe one concurrent write request. When a write request is processed, all other\nwrite request and all read requests have to wait.\n\nAll events are only persisted to disk, if `handle_request!` returns with Ok. On\nerror, all events gets discarded.\n\n\n## Database / Event Store Format\n\nAll written events are stored in one file, that is called `db.events` on\ndefault. The name can be changed with the argument `--events-file`. The file has\na binary format. It first contains the size of the first event, followed by the\nfirst event. Then the size of the second event, followed by the second event and\nso on.\n\nThe size of the event is written in the format provided by the go function\n[binary.PutUvarint](https://pkg.go.dev/encoding/binary#PutUvarint). For numbers\nup to 127, one byte is used. For numbers up to 16383, two bytes are used and so\non.\n\nThe format of the events will probably change in the future.\n\n\n## Build the platform\n\nTo build the platform from source, you need to install\n[roc](https://www.roc-lang.org/install), [go](https://go.dev/dl/) and\n[zig](https://ziglang.org/learn/getting-started/#installing-zig). Zig is used to\ncrosscompile the go code. Zig `0.14.0` is needed (not released at the moment of\nwriting).\n\nRun:\n\n    roc build.roc\n\nto build the platform for linux and mac.\n\nAfterwards, the example can be run with:\n\n    roc run examples/hello_world/main.roc\n\n\n## Known Issues\n\n* At the moment, Roc does not have atomic refcounts. This means, that the\nparallel handling of read requests are not thread safe. Read requests can\ntherefore crash the platform. [I hope, atomic refcounts will land soon in\nRoc.](https://roc.zulipchat.com/#narrow/channel/395097-compiler-development/topic/simplify.20refcounting)\n\n* [100 % CPU usage when running the platform with `roc\nrun`](https://roc.zulipchat.com/#narrow/channel/302903-platform-development/topic/100.20.25.20CPU.20when.20calling.20.60roc.20run.60.20on.20a.20go.20platform).\nAs a workaround, you can first build your platform with `roc build` or use `roc\nrun` with `--optimize`.\n\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fostcar%2Fkingfisher","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fostcar%2Fkingfisher","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fostcar%2Fkingfisher/lists"}