From bdc9928db8c1bf75e1263b01c84587ad19ef16f1 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 27 Jun 2026 11:11:20 -0400 Subject: [PATCH] feat: init --- .gitignore | 33 + tl/.gitignore | 15 + tl/README.md | 194 + tl/dev/dev.sh | 19 + tl/dev/media_server.py | 117 + tl/dev/user.cljs | 8 + tl/package-lock.json | 273 + tl/package.json | 18 + tl/resources/public/index.html | 15 + tl/resources/public/one_two_three.otio | 91754 +++++++++++++++++++++++ tl/shadow-cljs.edn | 29 + tl/src/tl/config.cljs | 4 + tl/src/tl/core.cljs | 26 + tl/src/tl/db.cljs | 56 + tl/src/tl/events.cljs | 73 + tl/src/tl/marks.cljs | 89 + tl/src/tl/md.cljs | 59 + tl/src/tl/otio.cljs | 66 + tl/src/tl/subs.cljs | 94 + tl/src/tl/views.cljs | 335 + 20 files changed, 93277 insertions(+) create mode 100644 .gitignore create mode 100644 tl/.gitignore create mode 100644 tl/README.md create mode 100755 tl/dev/dev.sh create mode 100755 tl/dev/media_server.py create mode 100644 tl/dev/user.cljs create mode 100644 tl/package-lock.json create mode 100644 tl/package.json create mode 100644 tl/resources/public/index.html create mode 100644 tl/resources/public/one_two_three.otio create mode 100644 tl/shadow-cljs.edn create mode 100644 tl/src/tl/config.cljs create mode 100644 tl/src/tl/core.cljs create mode 100644 tl/src/tl/db.cljs create mode 100644 tl/src/tl/events.cljs create mode 100644 tl/src/tl/marks.cljs create mode 100644 tl/src/tl/md.cljs create mode 100644 tl/src/tl/otio.cljs create mode 100644 tl/src/tl/subs.cljs create mode 100644 tl/src/tl/views.cljs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6359c7c --- /dev/null +++ b/.gitignore @@ -0,0 +1,33 @@ +# Build output +/target/ +/checkouts/ +/out/ +/src/gen/ +public/js +resources/public/js/compiled/ + +# Clojure / Leiningen / shadow-cljs +pom.xml +pom.xml.asc +*.jar +.lein-* +.nrepl-port +.cpcache/ +.shadow-cljs/ +*-init.clj + +# Tooling caches (keep configs, drop caches) +.clj-kondo/.cache/ +.lsp/.cache/ + +# Node +node_modules/ + +# Logs +*.log + +# Editors / OS +*.iml +.idea/ +.vscode/ +.DS_Store diff --git a/tl/.gitignore b/tl/.gitignore new file mode 100644 index 0000000..d785b67 --- /dev/null +++ b/tl/.gitignore @@ -0,0 +1,15 @@ +/out/ +/resources/public/js/compiled/ +/target/ +/*-init.clj +/*.log + +# Leiningen +/.lein-* +/.nrepl-port + +# Node.js dependencies +/node_modules/ + +# shadow-cljs cache, port files +/.shadow-cljs/ diff --git a/tl/README.md b/tl/README.md new file mode 100644 index 0000000..2a4e228 --- /dev/null +++ b/tl/README.md @@ -0,0 +1,194 @@ +# tl + +A [re-frame](https://github.com/day8/re-frame) application designed to ... well, that part is up to +you. + +## Getting Started + +### Project Overview + +* Architecture: +[Single Page Application (SPA)](https://en.wikipedia.org/wiki/Single-page_application) +* Languages + - Front end is [ClojureScript](https://clojurescript.org/) with ([re-frame](https://github.com/day8/re-frame)) +* Dependencies + - UI framework: [re-frame](https://github.com/day8/re-frame) + ([docs](https://github.com/day8/re-frame/blob/master/docs/README.md), + [FAQs](https://github.com/day8/re-frame/blob/master/docs/FAQs/README.md)) -> + [Reagent](https://github.com/reagent-project/reagent) -> + [React](https://github.com/facebook/react) +* Build tools + - CLJS compilation, dependency management, REPL, & hot reload: [`shadow-cljs`](https://github.com/thheller/shadow-cljs) +* Development tools + - Debugging: [CLJS DevTools](https://github.com/binaryage/cljs-devtools) + +#### Directory structure + +* [`/`](/../../): project config files +* [`dev/`](dev/): source files compiled only with the [dev](#running-the-app) profile + - [`user.cljs`](dev/cljs/user.cljs): symbols for use during development in the +[ClojureScript REPL](#connecting-to-the-browser-repl-from-a-terminal) +* [`resources/public/`](resources/public/): SPA root directory; +[dev](#running-the-app) / [prod](#production) profile depends on the most recent build + - [`index.html`](resources/public/index.html): SPA home page + - Dynamic SPA content rendered in the following `div`: + ```html +
+ ``` + - Customizable; add headers, footers, links to other scripts and styles, etc. + - Generated directories and files + - Created on build with either the [dev](#running-the-app) or [prod](#production) profile + - `js/compiled/`: compiled CLJS (`shadow-cljs`) + - Not tracked in source control; see [`.gitignore`](.gitignore) +* [`src/tl/`](src/tl/): SPA source files (ClojureScript, +[re-frame](https://github.com/Day8/re-frame)) + - [`core.cljs`](src/tl/core.cljs): contains the SPA entry point, `init` +* [`.github/workflows/`](.github/workflows/): contains the +[github actions](https://github.com/features/actions) pipelines. + - [`test.yaml`](.github/workflows/test.yaml): Pipeline for testing. + + +### Editor/IDE + +Use your preferred editor or IDE that supports Clojure/ClojureScript development. See +[Clojure tools](https://clojure.org/community/resources#_clojure_tools) for some popular options. + +### Environment Setup + +1. Install [JDK 8 or later](https://openjdk.java.net/install/) (Java Development Kit) +2. Install [Node.js](https://nodejs.org/) (JavaScript runtime environment) which should include + [NPM](https://docs.npmjs.com/cli/npm) or if your Node.js installation does not include NPM also install it. +5. Clone this repo and open a terminal in the `tl` project root directory + +### Browser Setup + +Browser caching should be disabled when developer tools are open to prevent interference with +[`shadow-cljs`](https://github.com/thheller/shadow-cljs) hot reloading. + +Custom formatters must be enabled in the browser before +[CLJS DevTools](https://github.com/binaryage/cljs-devtools) can display ClojureScript data in the +console in a more readable way. + +#### Chrome/Chromium + +1. Open [DevTools](https://developers.google.com/web/tools/chrome-devtools/) (Linux/Windows: `F12` +or `Ctrl-Shift-I`; macOS: `⌘-Option-I`) +2. Open DevTools Settings (Linux/Windows: `?` or `F1`; macOS: `?` or `Fn+F1`) +3. Select `Preferences` in the navigation menu on the left, if it is not already selected +4. Under the `Network` heading, enable the `Disable cache (while DevTools is open)` option +5. Under the `Console` heading, enable the `Enable custom formatters` option + +#### Firefox + +1. Open [Developer Tools](https://developer.mozilla.org/en-US/docs/Tools) (Linux/Windows: `F12` or +`Ctrl-Shift-I`; macOS: `⌘-Option-I`) +2. Open [Developer Tools Settings](https://developer.mozilla.org/en-US/docs/Tools/Settings) +(Linux/macOS/Windows: `F1`) +3. Under the `Advanced settings` heading, enable the `Disable HTTP Cache (when toolbox is open)` +option + +Unfortunately, Firefox does not yet support custom formatters in their devtools. For updates, follow +the enhancement request in their bug tracker: +[1262914 - Add support for Custom Formatters in devtools](https://bugzilla.mozilla.org/show_bug.cgi?id=1262914). + +## Development + +### Running the App + +Start a temporary local web server, build the app with the `dev` profile, and serve the app, +browser test runner and node test runner with hot reload: + +```sh +npm install +npx shadow-cljs watch app +``` + +Please be patient; it may take over 20 seconds to see any output, and over 40 seconds to complete. + +When `[:app] Build completed` appears in the output, browse to +[http://localhost:8280/](http://localhost:8280/). + +[`shadow-cljs`](https://github.com/thheller/shadow-cljs) will automatically push ClojureScript code +changes to your browser on save. To prevent a few common issues, see +[Hot Reload in ClojureScript: Things to avoid](https://code.thheller.com/blog/shadow-cljs/2019/08/25/hot-reload-in-clojurescript.html#things-to-avoid). + +Opening the app in your browser starts a +[ClojureScript browser REPL](https://clojurescript.org/reference/repl#using-the-browser-as-an-evaluation-environment), +to which you may now connect. + +#### Connecting to the browser REPL from your editor + +See +[Shadow CLJS User's Guide: Editor Integration](https://shadow-cljs.github.io/docs/UsersGuide.html#_editor_integration). +Note that `npm run watch` runs `npx shadow-cljs watch` for you, and that this project's running build ids is +`app`, `browser-test`, `node-test`, or the keywords `:app`, `:browser-test`, `:node-test` in a Clojure context. + +Alternatively, search the web for info on connecting to a `shadow-cljs` ClojureScript browser REPL +from your editor and configuration. + +For example, in Vim / Neovim with `fireplace.vim` +1. Open a `.cljs` file in the project to activate `fireplace.vim` +2. In normal mode, execute the `Piggieback` command with this project's running build id, `:app`: + ```vim + :Piggieback :app + ``` + +#### Connecting to the browser REPL from a terminal + +1. Connect to the `shadow-cljs` nREPL: + ```sh + lein repl :connect localhost:8777 + ``` + The REPL prompt, `shadow.user=>`, indicates that is a Clojure REPL, not ClojureScript. + +2. In the REPL, switch the session to this project's running build id, `:app`: + ```clj + (shadow.cljs.devtools.api/nrepl-select :app) + ``` + The REPL prompt changes to `cljs.user=>`, indicating that this is now a ClojureScript REPL. +3. See [`user.cljs`](dev/cljs/user.cljs) for symbols that are immediately accessible in the REPL +without needing to `require`. + +### Running `shadow-cljs` Actions + +See a list of [`shadow-cljs CLI`](https://shadow-cljs.github.io/docs/UsersGuide.html#_command_line) +actions: +```sh +npx shadow-cljs --help +``` + +Please be patient; it may take over 10 seconds to see any output. Also note that some actions shown +may not actually be supported, outputting "Unknown action." when run. + +Run a shadow-cljs action on this project's build id (without the colon, just `app`): +```sh +npx shadow-cljs app +``` +### Debug Logging + +The `debug?` variable in [`config.cljs`](src/cljs/tl/config.cljs) defaults to `true` in +[`dev`](#running-the-app) builds, and `false` in [`prod`](#production) builds. + +Use `debug?` for logging or other tasks that should run only on `dev` builds: + +```clj +(ns tl.example + (:require [tl.config :as config]) + +(when config/debug? + (println "This message will appear in the browser console only on dev builds.")) +``` + +## Production + +Build the app with the `prod` profile: + +```sh +npm install +npm run release +``` + +Please be patient; it may take over 15 seconds to see any output, and over 30 seconds to complete. + +The `resources/public/js/compiled` directory is created, containing the compiled `app.js` and +`manifest.edn` files. diff --git a/tl/dev/dev.sh b/tl/dev/dev.sh new file mode 100755 index 0000000..5510eea --- /dev/null +++ b/tl/dev/dev.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash +# Dev launcher: runs the shadow-cljs watch AND the range-capable media server +# together, and tears both down on exit (Ctrl-C kills the whole group). +# +# npm run dev +# +set -euo pipefail +cd "$(dirname "$0")/.." + +cleanup() { kill 0 2>/dev/null || true; } +trap cleanup EXIT INT TERM + +echo "[dev] starting media server (port ${MEDIA_PORT:-8281}, range-capable, autoreload)" +python3 dev/media_server.py & + +echo "[dev] starting shadow-cljs watch app (port 8280)" +npx shadow-cljs watch app & + +wait diff --git a/tl/dev/media_server.py b/tl/dev/media_server.py new file mode 100755 index 0000000..71ff5d6 --- /dev/null +++ b/tl/dev/media_server.py @@ -0,0 +1,117 @@ +#!/usr/bin/env python3 +"""Range-capable static file server for dev media (video). + +shadow-cljs :dev-http and Python's stdlib http.server both ignore the HTTP +Range header and answer 200 with the whole file. Safari/iOS refuse to play +an HTML5