create-clojurific 0.12.6 → 0.12.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,9 +8,9 @@ Scaffolds a ClojureScript project compiled by
8
8
  npm create clojurific@latest
9
9
  ```
10
10
 
11
- It asks for the project's name, a framework (Vanilla, [Reagent](https://reagent-project.github.io)
12
- or [UIx](https://github.com/pitch-io/uix)), and whether to install the
13
- dependencies and start the dev server. The project's namespace comes from its
11
+ It asks for the project's name, a framework (Vanilla, [Reagent](https://reagent-project.github.io/),
12
+ [UIx](https://uix-cljs.dev/), or [Hono](https://hono.dev/) for a backend), and
13
+ whether to install the dependencies and start the dev server. The project's namespace comes from its
14
14
  name: `my-app` gets `src/my_app/core.cljs`, `my-app.core`. The compiler needs
15
15
  Node.js 20 and Java 17 or later; when Java is missing, it offers to download
16
16
  Eclipse Temurin before starting the dev server.
@@ -19,16 +19,22 @@ Projects have the scripts `dev` (Vite's dev server, hot reloading), `build`,
19
19
  `preview`, and `repl`, a ClojureScript REPL evaluating in the pages the dev
20
20
  server runs (`cljf repl`, through the dev server's nREPL server).
21
21
 
22
+ The Hono project is a backend without pages: its app is a namespace the dev
23
+ server runs with [`@hono/vite-dev-server`](https://github.com/honojs/vite-plugins),
24
+ hot reloading it, and its REPL evaluates there. `build` bundles it into a
25
+ Node.js server, `dist/index.js`, which `start` runs.
26
+
22
27
  The options answer the questions, i.e. in scripts:
23
28
 
24
29
  ```sh
25
30
  npm create clojurific@latest my-app -- --template reagent
26
31
  npm create clojurific@latest my-app -- --template uix --immediate
32
+ npm create clojurific@latest my-api -- --template hono
27
33
  ```
28
34
 
29
35
  | Option | |
30
36
  |---|---|
31
- | `-t`, `--template <name>` | `vanilla`, `reagent` or `uix` |
37
+ | `-t`, `--template <name>` | `vanilla`, `reagent`, `uix` or `hono` |
32
38
  | `--overwrite` | remove the target directory's files |
33
39
  | `-i`, `--immediate` | install the dependencies and start the dev server |
34
40
  | `--no-interactive` | don't ask, use the defaults (`vanilla`, no install) |
package/create.js CHANGED
@@ -12,7 +12,7 @@ export const version = JSON.parse(readFileSync(path.join(packageRoot, 'package.j
12
12
 
13
13
  export const templatesDir = path.join(packageRoot, 'templates');
14
14
 
15
- export const TEMPLATES = ['vanilla', 'reagent', 'uix'];
15
+ export const TEMPLATES = ['vanilla', 'reagent', 'uix', 'hono'];
16
16
 
17
17
  export const DEFAULT_PROJECT = 'clojurific-project';
18
18
 
package/index.js CHANGED
@@ -27,8 +27,9 @@ Options:
27
27
 
28
28
  const FRAMEWORKS = [
29
29
  { value: 'vanilla', label: 'Vanilla', color: c.yellow },
30
- { value: 'reagent', label: 'Reagent', color: c.cyan },
31
- { value: 'uix', label: 'UIx', color: c.magenta },
30
+ { value: 'reagent', label: 'Reagent', color: c.cyan, hint: 'https://reagent-project.github.io/' },
31
+ { value: 'uix', label: 'UIx', color: c.magenta, hint: 'https://uix-cljs.dev/' },
32
+ { value: 'hono', label: 'Hono (backend only)', color: c.red, hint: 'https://hono.dev/' },
32
33
  ];
33
34
 
34
35
  function parse(argv) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-clojurific",
3
- "version": "0.12.6",
3
+ "version": "0.12.7",
4
4
  "description": "Scaffolds a ClojureScript project compiled by Clojurific and bundled by Vite: npm create clojurific@latest",
5
5
  "license": "EPL-1.0",
6
6
  "repository": {
package/prompts.js CHANGED
@@ -129,9 +129,14 @@ export function text({ message, placeholder = '', defaultValue = '' }) {
129
129
  });
130
130
  }
131
131
 
132
- /** One of options ({value, label, color}), initialValue first. */
132
+ /** One of options ({value, label, color, hint}), initialValue first. */
133
133
  export function select({ message, options, initialValue }) {
134
134
  const paint = option => (option.color ? option.color(option.label) : option.label);
135
+ // hints (i.e. links) aligned after the longest label
136
+ const width = Math.max(...options.map(o => o.label.length));
137
+ const line = option => (option.hint
138
+ ? `${paint(option)}${' '.repeat(width - option.label.length + 2)}${c.dim(option.hint)}`
139
+ : paint(option));
135
140
  return prompt({
136
141
  state: { index: Math.max(0, options.findIndex(o => o.value === initialValue)) },
137
142
  value: s => options[s.index].value,
@@ -142,8 +147,8 @@ export function select({ message, options, initialValue }) {
142
147
  },
143
148
  render(s, status) {
144
149
  const lines = options.map((option, i) => (i === s.index
145
- ? `${c.green(S.radioOn)} ${paint(option)}`
146
- : `${c.dim(S.radioOff)} ${c.dim(paint(option))}`));
150
+ ? `${c.green(S.radioOn)} ${line(option)}`
151
+ : `${c.dim(S.radioOff)} ${c.dim(line(option))}`));
147
152
  lines.push(`${c.dim('↑/↓')} to navigate ${c.dim('•')} ${c.dim('Enter:')} confirm`);
148
153
  return title(message, status) + body(status, lines, paint(options[s.index]));
149
154
  },
@@ -0,0 +1,25 @@
1
+ # {{name}}
2
+
3
+ A [Hono](https://hono.dev) backend in ClojureScript, compiled by
4
+ [Clojurific](https://github.com/WhimsicalCode/clojurific) and bundled by
5
+ [Vite](https://vite.dev).
6
+
7
+ - `npm run dev` starts the dev server, which hot reloads changed namespaces
8
+ - `npm run repl` starts a ClojureScript REPL evaluating in the backend the dev
9
+ server runs (start `npm run dev` first)
10
+ - `npm run build` bundles the backend into `dist/index.js`, a Node.js server
11
+ (no `node_modules` needed)
12
+ - `npm start` runs it (on port 3000)
13
+
14
+ The app is `src/{{nsDir}}/core.cljs`. It's compiled as a `:js-entries` module
15
+ exporting the app (see `vite.config.mjs`), which
16
+ [`@hono/vite-dev-server`](https://github.com/honojs/vite-plugins) serves and
17
+ `@hono/vite-build` bundles. Changed namespaces are hot reloaded in place:
18
+ `defonce` keeps its value.
19
+
20
+ ClojureScript dependencies go in `deps.edn`, npm packages in `package.json`.
21
+ The compiler needs Java 17 or later: `npx cljf setup-java` downloads one.
22
+
23
+ Editors connect to the dev server's nREPL server, its port in `.nrepl-port`
24
+ (i.e. Calva's "Connect to a running REPL", CIDER's `cider-connect-clj`), and
25
+ evaluate `(cljf.esm.repl/repl)` to switch the session to ClojureScript.
@@ -0,0 +1,8 @@
1
+ node_modules
2
+ dist
3
+ target
4
+ .cljf
5
+ .cpcache
6
+ .nrepl-port
7
+ *.local
8
+ .DS_Store
@@ -0,0 +1,3 @@
1
+ {:paths ["src"]
2
+ :deps {;; the dev server's nREPL server, for npm run repl and editors
3
+ nrepl/nrepl {:mvn/version "1.8.0"}}}
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "clojurific-project",
3
+ "private": true,
4
+ "version": "0.0.0",
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "vite",
8
+ "build": "vite build",
9
+ "start": "node dist/index.js",
10
+ "repl": "cljf repl"
11
+ },
12
+ "dependencies": {
13
+ "@hono/node-server": "^2.1.4",
14
+ "hono": "^4.13.13"
15
+ },
16
+ "devDependencies": {
17
+ "@hono/vite-build": "^1.11.1",
18
+ "@hono/vite-dev-server": "^0.26.1",
19
+ "clojurific": "*",
20
+ "vite": "^8.3.3"
21
+ }
22
+ }
@@ -0,0 +1,14 @@
1
+ (ns {{ns}}
2
+ (:require ["hono" :refer [Hono]]))
3
+
4
+ ;; kept across hot reloads
5
+ (defonce clicks (atom 0))
6
+
7
+ (defn- state [c]
8
+ (.json c #js {:clicks @clicks}))
9
+
10
+ (def app
11
+ (doto (Hono.)
12
+ (.get "/" (fn [c] (.text c "Hello Hono! Edit src/{{nsDir}}/core.cljs and save to hot reload")))
13
+ (.get "/clicks" state)
14
+ (.post "/clicks" (fn [c] (swap! clicks inc) (state c)))))
@@ -0,0 +1,33 @@
1
+ import cljs from 'clojurific/vite';
2
+ import devServer from '@hono/vite-dev-server';
3
+ import build from '@hono/vite-build/node';
4
+
5
+ // the backend: a module exporting the Hono app (:js-entries below)
6
+ const entry = 'target/cljs/cljs-esm-entries/server.js';
7
+
8
+ export default {
9
+ plugins: [
10
+ cljs({
11
+ outputDir: 'target/cljs',
12
+ compilerOptions: {
13
+ 'js-entries': { server: { exports: { default: "'{{ns}}/app" } } },
14
+ // the dev server starts an nREPL server, its port in .nrepl-port
15
+ repl: { 'nrepl-port': 0 },
16
+ },
17
+ // the dev server runs the backend once compiled, not on its first
18
+ // request: the REPL evaluates in it
19
+ ssrEntries: ['server'],
20
+ // no pages, no manifest of their scripts
21
+ manifest: false,
22
+ }),
23
+ devServer({
24
+ entry,
25
+ // ssrLoadModule's runner has no HMR, it would re-run a changed module
26
+ // (and its importers), the ssr environment's runner hot reloads
27
+ // namespaces in place: defonce keeps its value
28
+ loadModule: async (server, entry) => (await server.environments.ssr.runner.import(entry)).default,
29
+ }),
30
+ // the cljs plugin minifies, after pruning unused protocol implementations
31
+ build({ entry, emptyOutDir: true, minify: false }),
32
+ ],
33
+ };