{"id":15010340,"url":"https://github.com/agzam/unabomber","last_synced_at":"2026-03-09T18:32:48.661Z","repository":{"id":223964717,"uuid":"762032595","full_name":"agzam/unabomber","owner":"agzam","description":"Giantbomb API search app prototype","archived":false,"fork":false,"pushed_at":"2024-02-23T21:51:22.000Z","size":88,"stargazers_count":0,"open_issues_count":3,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-12-12T21:36:16.001Z","etag":null,"topics":["clojure","clojurescript","demo-app"],"latest_commit_sha":null,"homepage":"https://unabomber-1.onrender.com/","language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/agzam.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"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}},"created_at":"2024-02-23T00:22:08.000Z","updated_at":"2024-02-23T08:58:34.000Z","dependencies_parsed_at":null,"dependency_job_id":"b4bf2bb0-18da-461f-bbfa-7fe0fff6b95a","html_url":"https://github.com/agzam/unabomber","commit_stats":null,"previous_names":["agzam/unabomber"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/agzam/unabomber","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/agzam%2Funabomber","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/agzam%2Funabomber/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/agzam%2Funabomber/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/agzam%2Funabomber/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/agzam","download_url":"https://codeload.github.com/agzam/unabomber/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/agzam%2Funabomber/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30307342,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-09T17:35:44.120Z","status":"ssl_error","status_checked_at":"2026-03-09T17:35:43.707Z","response_time":61,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["clojure","clojurescript","demo-app"],"created_at":"2024-09-24T19:33:39.006Z","updated_at":"2026-03-09T18:32:48.629Z","avatar_url":"https://github.com/agzam.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Prototype app for showcasing GiantBomb API search\n\nTry it here: https://unabomber-1.onrender.com\n\nNote that it's deployed on a free tier, so it might load extremely slowly (be patient, it's unlikely that it's broken, it just takes too long to load) and search too, will get super sluggish. I mean, you may have to wait for like two-three minutes for search results to appear.\n\n## Running locally\n### Required\n\n- functional GiantBombAPI key. [Sign up and get the key here](https://www.giantbomb.com/api/)\n\n### Using the Docker Image\n\n1. clone the repo\n    ```bash\n    git clone https://github.com/agzam/unabomber\n    cd unabomber\n    ```\n\n2. build the image\n\n    ```bash\n    sudo docker build -t unabomber .\n    ```\n\n3. run the app\n\n    providing the API key: \n\n    ```bash\n    sudo docker run -p 3000:3000 --name bomba unabomber \\\n    java -jar /unabomber.jar  \\\n    --api-key=\"YOUR-API-KEY\"\n    ```\n\n    ```bash\n    open localhost:3000\n    ```\n\n### Running/testing locally without Docker\n\n#### Prerequisites\n\n- clojure-cli, [installation instructions](https://clojure.org/guides/install_clojure)\n- nodejs, either install it directly, via package manager, or use [nvm](https://github.com/nvm-sh/nvm)\n- configured local gpg service (required for storing the API key)\n\n##### Store API-KEY in an encrypted file\n\nRun the following command while in the project directory, *supplement your GiantBombAPI key and the email used with your private gpg key*:\n\n```bash\necho '{:giantbomb-api-key \"YOUR-API-KEY\"}' | \\ \n    gpg --recipient YOUR@EMAIL.COM \\\n    --output ./resources/creds.gpg --encrypt\n```\n\nThe app then uses that info while keeping your API key secured. **If that step is not done, the search won't work at all**.\n\n##### Install required npm packages\n\n```bash\nnpm install\n```\n\n#### Build and run \n\n```bash\nclojure -T:build uberjar\n```\n\nThis would build the standalone jar with minified JavaScript.\n\nThen you can run it locally:\n\n```bash\njava -jar ./target/unabomber.jar \n```\n\nThe standalone jar would run the server on port 3000\n\n```bash\nopen localhost:3000\n```\n\n### To study the code, the best is to run the app in the REPL\n\nInstead of running the standalone \"production-ready\" app, you may choose to run the \"dev-grade\" app (that lacks all optimizations for faster feedback loop) in the REPL. That is the best option to navigate through the code and to understand how things are stitched together. In general, exploring any kind of Lisp code while having a connected REPL session is a much more delightful experience.\n\nPlease avoid running both options (the \"prod\" jar and the \"dev\" REPL) at the same time. While theoretically they should not conflict, I have not tested this scenario, so some unexpected issues could arise.\n\n```bash\nclojure -M:dev:backend:frontend \n```\n\nThat should open the REPL. Once in there:\n\n```clojure\nuser\u003e (go)\n```\n\nThat will kick off the \"assembling the system\" process using Integrant. Then the server would be available on port 3003. Or whatever is configured in `/dev/config.edn`\n\n```bash\nopen localhost:3003\n```\n\n**Remember, prod version and dev version use different ports**, so they can run without conflicting with each other. Still, it's probably best not to run both at the same time.\n\n#### Emacs \u0026 CIDER \n\nIt is, of course possible to REPL with VSCode and IntelliJ and Vim, etc., but I only did this in Emacs.\n\n- Default option is to run a single REPL. You can simply run `cider-jack-in` and type `(go)` in the REPL. All required elisp vars would be initialized with proper values, see: `./.dir-locals.el`\n\n- Or, you may like to run two simultaneous REPLs - for both, Clojure and Clojurescript. Then evaling Clojure code would go to clj REPL and Clojurescript code would got into the browser REPL. Simply, run `M-x cider-jack-in-clj\u0026cljs`, and type `(go)` inside the Clojure REPL.\n\n  That should start `shadow-cljs` compilation and `postcss` watchers, they'd be running in the sibling Clojurescript REPL. Once you open the app in the browser, REPL would automatically connect to it. Try typing something like `(js/alert)` - the dialog in the browser would pop-up, proving that cljs REPL is connected.\n\n## Project components\n\n### shadow-cljs\nAll front-end dependencies are in `./deps.edn` and `./package.json`\n\nshadow-cljs setup pretty much follows the official guide; there's nothing unorthodox there, see: https://shadow-cljs.github.io/docs/UsersGuide.html\n\n### tailwind CSS\nhttps://tailwindcss.com/docs\n\nTailwind CSS class names get collected via `postcss` build process, see `package.json -\u003e scripts` section\n\n### re-frame\nhttps://day8.github.io/re-frame\n\nThe project's structure follows general conventions for re-frame projects. \n\n### reitit\nhttps://github.com/metosin/reitit\n\nused for routing, both on front and back-end. The simplest way for newcomers to go through the code is probably to start at the entry point for the routes. On front-end that would be in `frontend/routing.cljs`, server routes are in `backend/system.clj`. There's tons of boilerplate in the `unabomber.backend.system` namespace, specifically in the middleware section. Most of it can probably be removed, I just decided not to waste time fixing what's not broken, try not to get too caught up in it, it's not super important. \n\n### integrant\nhttps://github.com/weavejester/integrant\n\nis used for \"assembling the system\", it's useful to reset the server when you make changes to the backend code, without having to restart the whole thing. Simply run `(reset)`, in the Clojure REPL.\n\n## Testing\n\nThere is a basic framework for testing. Backend test are pretty straightforward. Front-end tests are for now only cover unit testing and run with [Karma](https://karma-runner.github.io/latest/index.html). I'm hoping to add some end-to-end tests with Cypress at some point. \n\nThe best way to start examining tests and how they pieced together, is to start at GitHub Actions workflow file - `.github/workflows/unabomber.yml`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fagzam%2Funabomber","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fagzam%2Funabomber","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fagzam%2Funabomber/lists"}