@johnhenry/sitefile 0.0.1 → 0.0.2

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/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.0.2 (2026-11-08)
4
+
5
+ - **Plugin console output keeps its order** (johnhenry/sitefile#164): a
6
+ plugin's console lines are written before its result, in both the
7
+ TypeScript and Rust runners, so they always become build warnings (a race
8
+ dropped some). Fixed in 5689229 (#164).
9
+ - **Docs: the tool is "sitefile".** The product name is lowercase where it
10
+ stands alone; "Sitefile" stays for the file (`Sitefile`, `Sitefile.lock`, "a
11
+ Sitefile") and the language. The desktop app is Sitefile Desktop.
12
+
3
13
  ## 0.0.1 (2026-11-08)
4
14
 
5
15
  - **`serve` serves archive files** (johnhenry/sitefile#155): `sitefile serve
@@ -34,7 +44,7 @@
34
44
  conformance cases. Added in c131eb3 (#162).
35
45
 
36
46
  - **Library API for embedders** (johnhenry/sitefile#153), found by embedding
37
- the crate in sitefile Desktop. Rust: `servers::serve_detached`,
47
+ the crate in Sitefile Desktop. Rust: `servers::serve_detached`,
38
48
  `restart_detached`, `start_detached`, `stop_server`, `resolve_source`,
39
49
  `parse_publish` and `DetachedServe` (the CLI's `serve -d`, `server restart`
40
50
  and `server stop` now call them); `executor::store_build_as_image` with
@@ -77,7 +87,7 @@
77
87
  johnhenry/sitefile#145). A JavaScript plugin renders a `@johnhenry/fileable`
78
88
  tree into the build with fileable's in-memory `toFiles()` and returns
79
89
  `{ files }`, so a JSX file tree needs no directory or zip on disk in
80
- between. fileable stays out of Sitefile's dependencies: it is a
90
+ between. fileable stays out of sitefile's dependencies: it is a
81
91
  devDependency, and `examples/fileable/vendor.mjs` copies the files its
82
92
  browser entry point loads into the plugin folder (gitignored; nothing
83
93
  generated is committed), the only folder a plugin can read. Its `cmd`
@@ -106,7 +116,7 @@
106
116
 
107
117
  ## 0.0.0 — first npm release (2026-11-06)
108
118
 
109
- `@johnhenry/sitefile` is a new package: Sitefile was never published to npm
119
+ `@johnhenry/sitefile` is a new package: sitefile was never published to npm
110
120
  under any name, and `0.0.0` is its first version. It joins the @johnhenry
111
121
  family as its static build orchestrator, next to `@johnhenry/fileable` (file
112
122
  trees in JSX) and `@johnhenry/packfile` (the Web Bundle reader and server).
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Sitefile
1
+ # sitefile
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/%40johnhenry%2Fsitefile.svg)](https://www.npmjs.com/package/@johnhenry/sitefile)
4
4
  [![CI](https://github.com/johnhenry/sitefile/actions/workflows/ci.yml/badge.svg)](https://github.com/johnhenry/sitefile/actions/workflows/ci.yml)
@@ -325,7 +325,7 @@ stopgap in VS Code.
325
325
  - [docs/RUST.md](docs/RUST.md) — the Rust port: layout, parity checks, known differences
326
326
  - [docs/LSP.md](docs/LSP.md) — the language server for editors (`sitefile lsp`, Rust binary)
327
327
  - [docs/PLUGINS.md](docs/PLUGINS.md) — writing renderer plugins, and the sandbox
328
- - [docs/DOCKER.md](docs/DOCKER.md) — Sitefile next to Docker: site images Docker runs, Dockerfile stages, shared registries
328
+ - [docs/DOCKER.md](docs/DOCKER.md) — sitefile next to Docker: site images Docker runs, Dockerfile stages, shared registries
329
329
  - [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) — invariants and module layout
330
330
  - [docs/MILESTONES.md](docs/MILESTONES.md), [docs/TASKS.md](docs/TASKS.md)
331
331
  - [AGENTS.md](AGENTS.md) — the verification loop and rules for anyone (human or agent) changing this repo
@@ -380,7 +380,7 @@ stage), so building one is treated as running untrusted input. Templates,
380
380
  imports and WebAssembly plugins are data; JavaScript plugins and external
381
381
  tools are code, and run only when you name them on the command line.
382
382
 
383
- **What Sitefile guarantees:**
383
+ **What sitefile guarantees:**
384
384
 
385
385
  - **Local reads stay inside the build context.** No `..`, absolute paths or
386
386
  symlinks out; hard-linked files are refused (`E_HARDLINK`) unless
@@ -447,14 +447,14 @@ tools are code, and run only when you name them on the command line.
447
447
  `INTEGRITY`, `@sha256:` and `--strict-pins` for builds that must be
448
448
  reproducible.
449
449
  - **Web Bundles are unsigned.** `EXPORT … AS wbn` writes an unsigned b2 bundle;
450
- signing (for example for an Isolated Web App) happens outside Sitefile.
450
+ signing (for example for an Isolated Web App) happens outside sitefile.
451
451
  - **Widening flags are yours to justify.** `--allow-http`,
452
452
  `--allow-private-network`, `--allow-hardlinks`, `--force` and `serve -p
453
453
  0.0.0.0:…` each turn off one of the guarantees above for that build.
454
454
 
455
455
  ## Family
456
456
 
457
- Sitefile is the build orchestrator of the @johnhenry family's static tools. It
457
+ sitefile is the build orchestrator of the @johnhenry family's static tools. It
458
458
  runs the pipeline (pinned imports, stages, templates, sandboxed plugins, checks,
459
459
  exports); its siblings write file trees in code and serve the result. It has no
460
460
  runtime dependency on either: they meet at file formats, a directory, a zip or
@@ -462,7 +462,7 @@ a `.wbn` Web Bundle.
462
462
 
463
463
  - **[`@johnhenry/fileable`](https://github.com/johnhenry/fileable)** -- writes
464
464
  file trees in JSX (`Dir`, `File`, `Rm`), for scaffolding and codegen. A
465
- fileable build's output is an ordinary Sitefile input. Neither package
465
+ fileable build's output is an ordinary sitefile input. Neither package
466
466
  depends on the other.
467
467
  - **[`@johnhenry/packfile`](https://github.com/johnhenry/packfile)** -- the
468
468
  family's Web Bundle reader and in-memory server. It reads what `EXPORT … AS
@@ -479,14 +479,14 @@ not published: the npm versions still behave as the rest of that row says.
479
479
 
480
480
  | From | To | How | Status |
481
481
  | --- | --- | --- | --- |
482
- | fileable, loose output | Sitefile | `COPY ./generated/ /` | Works |
483
- | fileable, `encode="zip"` | Sitefile | `IMPORT gen FROM ./site.zip AS tree`, then `COPY gen:/ /` | Works (same output as loose) |
484
- | fileable, `encode="wbn"` | Sitefile | `IMPORT … AS tree` | **Not yet:** it's gzip around a Web Bundle, and `AS tree` reads only plain bundles ([#141](https://github.com/johnhenry/sitefile/issues/141)) |
482
+ | fileable, loose output | sitefile | `COPY ./generated/ /` | Works |
483
+ | fileable, `encode="zip"` | sitefile | `IMPORT gen FROM ./site.zip AS tree`, then `COPY gen:/ /` | Works (same output as loose) |
484
+ | fileable, `encode="wbn"` | sitefile | `IMPORT … AS tree` | **Not yet:** it's gzip around a Web Bundle, and `AS tree` reads only plain bundles ([#141](https://github.com/johnhenry/sitefile/issues/141)) |
485
485
  | fileable tree, rendered during a build | Sitefile | a JavaScript `TRANSFORM` plugin calling fileable's in-memory `toFiles()` | An example on main, not part of the npm package: [`examples/fileable/`](examples/fileable/) ([#145](https://github.com/johnhenry/sitefile/issues/145)). fileable is vendored into the plugin folder; `cmd`, local `src=` and `env://` fail with `E_PLUGIN` |
486
- | Sitefile, `EXPORT / AS wbn BASE <url>` | packfile | `fromWebBundle(buffer, { baseURL })` from `@johnhenry/packfile/web-bundle`, then `createRouter(files)` | Works; tested here (`test/packfile-interop.test.ts`), and packfile's own tests read a bundle written by Sitefile 0.0.0 |
487
- | Sitefile `.wbn` | packfile `fromArchive()` | with 0.0.0 / 0.2.0: gzip it, and export with `BASE https://packfile.invalid/` | Works with that workaround. **Fixed on main, in the next release:** `EXPORT … AS wbn COMPRESSION gzip` (or `-o site.wbn.gz`) writes the gzip ([#143](https://github.com/johnhenry/sitefile/issues/143)), and `fromArchive()` takes a `baseURL` or the origin of the bundle's primary URL, so any `BASE` reads back ([packfile#18](https://github.com/johnhenry/packfile/issues/18)) |
488
- | Sitefile `HEADER` / `REDIRECT` | packfile `createWebBundleRouter()` | -- | **Not applied in 0.0.0:** only the `/_headers` and `/_redirects` files are in the bundle. **Fixed on main, in the next release:** each response carries its HEADER values, and exact-path 301/302/303/307/308 REDIRECTs are 3xx responses with `location` ([#144](https://github.com/johnhenry/sitefile/issues/144)). Splats, `200` rewrites and `404` rules stay in `/_redirects` only |
489
- | packfile `toArchive()` | Sitefile | `IMPORT … AS tree` | **Not yet** (same as fileable's `.wbn`, [#141](https://github.com/johnhenry/sitefile/issues/141)) |
486
+ | sitefile, `EXPORT / AS wbn BASE <url>` | packfile | `fromWebBundle(buffer, { baseURL })` from `@johnhenry/packfile/web-bundle`, then `createRouter(files)` | Works; tested here (`test/packfile-interop.test.ts`), and packfile's own tests read a bundle written by sitefile 0.0.0 |
487
+ | sitefile `.wbn` | packfile `fromArchive()` | with 0.0.0 / 0.2.0: gzip it, and export with `BASE https://packfile.invalid/` | Works with that workaround. **Fixed on main, in the next release:** `EXPORT … AS wbn COMPRESSION gzip` (or `-o site.wbn.gz`) writes the gzip ([#143](https://github.com/johnhenry/sitefile/issues/143)), and `fromArchive()` takes a `baseURL` or the origin of the bundle's primary URL, so any `BASE` reads back ([packfile#18](https://github.com/johnhenry/packfile/issues/18)) |
488
+ | sitefile `HEADER` / `REDIRECT` | packfile `createWebBundleRouter()` | -- | **Not applied in 0.0.0:** only the `/_headers` and `/_redirects` files are in the bundle. **Fixed on main, in the next release:** each response carries its HEADER values, and exact-path 301/302/303/307/308 REDIRECTs are 3xx responses with `location` ([#144](https://github.com/johnhenry/sitefile/issues/144)). Splats, `200` rewrites and `404` rules stay in `/_redirects` only |
489
+ | packfile `toArchive()` | sitefile | `IMPORT … AS tree` | **Not yet** (same as fileable's `.wbn`, [#141](https://github.com/johnhenry/sitefile/issues/141)) |
490
490
 
491
491
  Gotchas when serving a Sitefile bundle with packfile:
492
492
 
@@ -494,14 +494,14 @@ Gotchas when serving a Sitefile bundle with packfile:
494
494
  for `/docs/ünï/page.html` returns 404 because the pathname isn't
495
495
  percent-decoded; the string `"/docs/ünï/page.html"` works
496
496
  ([packfile#20](https://github.com/johnhenry/packfile/issues/20)).
497
- - **`fromWebBundle` skips the bundle's entry at the bare base URL.** Sitefile
497
+ - **`fromWebBundle` skips the bundle's entry at the bare base URL.** sitefile
498
498
  stores the index page there as well as at `/index.html`; you get it from
499
499
  `index.html`.
500
500
  - **The `baseURL` you pass to `fromWebBundle` must be the `BASE` you exported
501
501
  with.** Entries under any other origin are skipped, so the wrong base reads
502
502
  back as an empty map, without an error. packfile's `fromArchive()` on its
503
503
  main branch (next release) defaults to the origin of the primary URL, which
504
- Sitefile writes only when the site has `/index.html`; with a `BASE` that has
504
+ sitefile writes only when the site has `/index.html`; with a `BASE` that has
505
505
  a path (`https://site.example/blog/`), the keys start with `blog/` unless you
506
506
  pass that `baseURL`.
507
507
  - **HEADER and REDIRECT need `createWebBundleRouter()`** (on main, next
@@ -12,8 +12,9 @@ const MARK = '\u0000SITEFILE:';
12
12
  const RUNNER = String.raw `
13
13
  const MARK = '\u0000SITEFILE:';
14
14
  const send = (msg) => process.stdout.write(MARK + JSON.stringify(msg) + '\n');
15
- // Plugin console output goes to stderr so stdout stays a clean channel.
16
- for (const k of ['log', 'info', 'debug']) console[k] = (...a) => process.stderr.write(a.map(String).join(' ') + '\n');
15
+ // Plugin console output goes to stdout as unmarked lines, so it reaches the host before
16
+ // the result that follows it (stderr is another pipe, with no order against stdout).
17
+ for (const k of ['log', 'info', 'debug']) console[k] = (...a) => process.stdout.write(a.map(String).join(' ').split('\n').filter((l) => !l.startsWith(MARK)).join('\n') + '\n');
17
18
  const toB64 = (v) => Buffer.from(typeof v === 'string' ? Buffer.from(v, 'utf8') : v).toString('base64');
18
19
  const isBytes = (v) => typeof v === 'string' || v instanceof Uint8Array;
19
20
  let transform;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@johnhenry/sitefile",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "description": "Docker-inspired static artifact builder: compose immutable file trees from local and remote sources, render templates, and export a deployable site. No container runtime, no shell, no runtime dependencies.",
5
5
  "keywords": [
6
6
  "static-site",