defuss-ssg 0.6.3 → 0.7.0

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,7 +8,7 @@ Static site generation, request-time dev SSR, file-based endpoints, and producti
8
8
  - `build` renders static HTML, bundles client components, compiles endpoints, and copies assets.
9
9
  - `serve` serves built output with `defuss-express`, plus dynamic endpoints and optional RPC.
10
10
 
11
- Use Bun for package management. The published package targets Node `^20.19.0 || >=22.12.0`.
11
+ Use Bun for package management. The published package and the container runtime both target Node `^20.19.0 || >=22.12.0`.
12
12
 
13
13
  ## What It Supports
14
14
 
@@ -62,6 +62,7 @@ Minimal config:
62
62
  ```ts
63
63
  import { rehypePlugins, remarkPlugins, type SsgConfig } from "defuss-ssg";
64
64
 
65
+ // all of the fields are optional; you can also skip the file itself!
65
66
  const config: SsgConfig = {
66
67
  pages: "pages",
67
68
  output: "dist",
@@ -72,11 +73,19 @@ const config: SsgConfig = {
72
73
  remarkPlugins: [...remarkPlugins],
73
74
  rehypePlugins: [...rehypePlugins],
74
75
  rpc: true,
75
- };
76
+ // e.g. set defuss-ssg to use podman even if docker is available
77
+ containerRuntime: "docker",
78
+ // override Vite config
79
+ viteConfig: {
80
+ ...
81
+ },
82
+ } satisfies SsgConfig;
76
83
 
77
84
  export default config;
78
85
  ```
79
86
 
87
+ `containerRuntime` forces `docker` or `podman` for `docker-*` commands. `viteConfig` is merged into defuss-ssg's internal Vite config for both `dev` and `build`, so you can add aliases, plugins, server options, and similar Vite settings from `config.ts`.
88
+
80
89
  Example page:
81
90
 
82
91
  ```mdx
@@ -96,8 +105,16 @@ This page uses MDX, frontmatter, and a defuss component.
96
105
  Example component:
97
106
 
98
107
  ```tsx
99
- export function Button({ label }: { label: string }) {
100
- return <button type="button">{label}</button>;
108
+ import type { Props } from "defuss";
109
+
110
+ export interface ButtonProps extends Props {
111
+ label: string;
112
+ }
113
+
114
+ export function Button({ label }: ButtonProps) {
115
+ return (
116
+ <button type="button">{label}</button>
117
+ );
101
118
  }
102
119
  ```
103
120
 
@@ -121,6 +138,52 @@ defuss-ssg serve ./my-site
121
138
 
122
139
  `serve` expects existing build output in `dist/`, so run `build` first.
123
140
 
141
+ ## Docker and Podman
142
+
143
+ The primary container workflow is built into the CLI:
144
+
145
+ ```bash
146
+ bunx defuss-ssg docker-dev ./my-site
147
+ bunx defuss-ssg docker-build ./my-site
148
+ bunx defuss-ssg docker-serve ./my-site --multicore
149
+ ```
150
+
151
+ When you are working from this monorepo before the next npm publish, use the built local CLI instead of `bunx defuss-ssg`. `bunx defuss-ssg` resolves the last published package, so it will not see unreleased `docker-*` commands from this checkout:
152
+
153
+ ```bash
154
+ cd packages/ssg
155
+ bun run build
156
+ node ./dist/cli.mjs docker-dev ../../example-ssg --port 3111 --docker-args --network host
157
+ ```
158
+
159
+ Each `docker-*` command writes a temporary Dockerfile, builds a local `defuss-ssg` image, mounts your project at `/workspace`, mounts a deterministic container-managed `/workspace/node_modules` volume, and then runs the matching inner `defuss-ssg` command. The mounted project still owns its dependency graph: the container reads that project's `package.json`, uses its declared package manager, installs the project's dependencies, and then starts `dev`, `build`, or `serve`.
160
+
161
+ `docker-dev` and `docker-serve` automatically bind the inner service to `0.0.0.0` and publish the selected port. One published port is enough even with `--multicore`; `defuss-express` keeps worker ports internal and load-balances behind the public port.
162
+
163
+ Runtime selection:
164
+
165
+ - `docker` is preferred automatically when available
166
+ - `podman` is used automatically when Docker is unavailable
167
+ - Set `containerRuntime` in `config.ts` to force one runtime explicitly
168
+
169
+ ```ts
170
+ export default {
171
+ containerRuntime: "podman",
172
+ };
173
+ ```
174
+
175
+ Outer container runtime arguments can be forwarded with `--docker-args`. Everything after that marker is appended to the outer `docker run` or `podman run` call, while the arguments before it still go to the inner `defuss-ssg` command:
176
+
177
+ ```bash
178
+ bunx defuss-ssg docker-dev ./my-site --port 3000 --docker-args --network host
179
+ bunx defuss-ssg docker-serve ./my-site --multicore --docker-args --env NODE_ENV=production
180
+ ```
181
+
182
+ Good to know:
183
+ - The container runs the same `setup()` flow as local CLI usage.
184
+ - Use the generated container-managed `/workspace/node_modules` volume instead of bind-mounting host `node_modules` across OS or architecture boundaries.
185
+ - For manual container management, a static, minimal Dockerfile is available as `Dockerfile` too.
186
+
124
187
  ## How It Works
125
188
 
126
189
  ### Dev Mode
@@ -137,6 +200,45 @@ By default, the CLI keeps `dist/` refreshed during dev as a compatibility fallba
137
200
 
138
201
  `defuss-ssg serve` reads the built output from `dist/` and serves it with `defuss-express`. Dynamic endpoint modules are registered at runtime, and `rpc.ts` or `rpc.js` is compiled and initialized automatically when RPC is enabled and `defuss-rpc` is installed.
139
202
 
203
+ ## Content Discovery
204
+
205
+ For generation-time listings such as blog archives, `defuss-ssg` now exposes a small `glob()` API.
206
+
207
+ Use the virtual module inside MDX or other code that Vite evaluates for SSR:
208
+
209
+ ```ts
210
+ import { glob } from "virtual:defuss-ssg/content";
211
+
212
+ export const posts = (await glob("pages/blog/**/*.mdx")).sort((left, right) =>
213
+ String(right.meta.date || "").localeCompare(String(left.meta.date || "")),
214
+ );
215
+ ```
216
+
217
+ Use the direct package export in non-Vite server-side contexts such as `config.ts` or custom plugins:
218
+
219
+ ```ts
220
+ import { glob } from "defuss-ssg";
221
+
222
+ const posts = await glob("pages/blog/**/*.mdx", {
223
+ cwd: process.cwd(),
224
+ });
225
+ ```
226
+
227
+ Each entry contains:
228
+
229
+ - `filePath`: absolute file path
230
+ - `relativePath`: path relative to `cwd`
231
+ - `slug`: route-like identifier without a leading slash
232
+ - `route`: public route when the file lives under the configured `pages` directory
233
+ - `meta`: parsed YAML or TOML frontmatter
234
+
235
+ Notes:
236
+
237
+ - `cwd` defaults to the current working directory for the direct helper.
238
+ - The virtual module binds `cwd` and `pages` to the active SSG project automatically.
239
+ - `route` is only derived for files inside the configured `pages` directory.
240
+ - v1 returns metadata records only; it does not eagerly execute every matched MDX module.
241
+
140
242
  ## Endpoints
141
243
 
142
244
  Endpoint source files live under `pages/` and export HTTP method handlers.
@@ -195,9 +297,19 @@ When RPC is active, `defuss-ssg` exposes:
195
297
  - `POST /rpc`
196
298
  - `POST /rpc/schema`
197
299
 
198
- Set `rpc: false` in `config.ts` to disable RPC discovery.
300
+ Set `rpc: false` in `config.ts` to disable RPC auto-discovery.
301
+
302
+ To use the RPC in your client components, import the generated client helper:
303
+
304
+ ```ts
305
+ import { createRpcClient } from "defuss-ssg/rpc";
306
+
307
+ const rpc = createRpcClient();
308
+ const sum = await rpc.mathApi.add(2, 3);
309
+ console.log(sum); // 5
310
+ ```
199
311
 
200
- ## Plugins
312
+ ## Custom MDX plugins
201
313
 
202
314
  `defuss-ssg` plugins run in build order and can modify the pipeline at distinct phases.
203
315
 
@@ -275,7 +387,7 @@ Most projects only need the main package export.
275
387
  ## CLI Reference
276
388
 
277
389
  ```bash
278
- defuss-ssg [dev|build|serve] [folder] [--debug] [--multicore]
390
+ defuss-ssg [dev|build|serve|docker-dev|docker-build|docker-serve] [folder] [options]
279
391
 
280
392
  No args -> dev .
281
393
  Single path -> dev <path>
@@ -290,11 +402,18 @@ Commands:
290
402
  - `dev`: starts the Vite dev server on port `3000` by default
291
403
  - `build`: generates the static site into `dist/`
292
404
  - `serve`: serves the built output from `dist/`
405
+ - `docker-dev`: builds the generated image, mounts the project, and starts `dev` inside Docker or Podman
406
+ - `docker-build`: builds the generated image, mounts the project, and runs `build` inside Docker or Podman
407
+ - `docker-serve`: builds the generated image, mounts the project, and runs `serve` inside Docker or Podman
293
408
 
294
409
  Flags:
295
410
 
296
411
  - `--debug` or `-d`: enable verbose logging
297
412
  - `--multicore`: use `workers: "auto"` for `serve`
413
+ - `--host` or `-H <host>`: override the dev or serve bind host
414
+ - `--port` or `-p <port>`: override the dev or serve port
415
+ - `--skip-setup` or `--no-setup`: skip project dependency installation for prepared environments and containers
416
+ - `--docker-args <args...>`: forward everything after the marker to the outer `docker run` or `podman run` invocation used by `docker-*`
298
417
 
299
418
  ## Local Package Development
300
419