@zerotal/arch 1.13.1 → 1.13.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/docs/changelog.md CHANGED
@@ -27,6 +27,50 @@ the section for every version you cross and apply its migration notes, not only
27
27
  majors. [Releases and versioning](/docs/support-policy#releases-and-versioning) explains
28
28
  when that carve-out ends.
29
29
 
30
+ ## 1.13.2 — 2026-08-31
31
+
32
+ From a production field report at 1.12.0 — an Inertia + React app on SQLite, 117 routes,
33
+ 1256 tests, live behind Caddy. Six items, of which one was still open. The other five had
34
+ been closed between 1.10.0 and 1.13.0 and are listed at the end, because a report that
35
+ carries items forward is worth answering precisely rather than generally.
36
+
37
+ ### Fixed
38
+
39
+ - **`Inertia.stream()` honours `X-Inertia`.** It answered every request with `text/html`,
40
+ including the XHR a running Inertia client sends. So the obvious way to adopt server
41
+ rendering — point a route at `stream` — broke client-side navigation _to_ that route.
42
+
43
+ The shape of the failure is the reason it survived: the first load looks perfect, which
44
+ is what a person checks. The second click does nothing. It fails only for somebody
45
+ already in the app, silently, and only once the route otherwise works.
46
+
47
+ `render` and `stream` now share the branch that writes the page object rather than one
48
+ of them having it, which is precisely how they came apart. An app that wrote a header
49
+ check in front of the call can delete it; it does no harm either way.
50
+
51
+ ### Verified, not changed
52
+
53
+ Five of the six items were already closed. Each was re-checked against this release rather
54
+ than taken on trust, because the report carried them forward from 1.9.0:
55
+
56
+ - **STARTTLS on port 587** — fixed in 1.11.0, with `SmtpStartTls.test.ts` covering it. The
57
+ cause was that a write issued before the handshake completes is dropped.
58
+ - **`intended_url` across `Auth.attempt()`** — fixed in 1.11.0. `attempt` delegates to
59
+ `login`, `regenerate()` deliberately carries the data bag, and only privilege markers are
60
+ swept. `intendedFlow.test.ts` runs the three steps in order against a real session,
61
+ including the ID rotation.
62
+ - **`bun install --ignore-scripts`** — documented in the
63
+ [deployment guide](/docs/deployment).
64
+ - **A default test timeout** — `zt test` has passed `--timeout=30000` for some time, and
65
+ [the testing guide](/docs/testing#bun-test-vs-bun-zt-test) already names the two
66
+ alternatives that do not work: `bunfig.toml`'s `[test] timeout`, and
67
+ `setDefaultTimeout()` in a preload.
68
+ - **`postForm` refusing a `File`** — it has thrown, naming `multipart()`, since 1.0.2.
69
+
70
+ The report's other upload concern — that `http.file()` consumes the multipart stream, so a
71
+ later `body()` reads empty — **does not reproduce**: `_parseFormData()` caches, and reading
72
+ the file first is safe. A test now pins that, since nothing had covered that order.
73
+
30
74
  ## 1.13.1 — 2026-08-31
31
75
 
32
76
  One addition, found by sizing a job rather than doing it.
@@ -89,12 +89,23 @@ export class PostController {
89
89
  | Response body | Fully buffered string | Streaming `ReadableStream` |
90
90
  | TTFB | Immediate | After the shell is ready |
91
91
  | Page `<Head>` | Client only | Collected into the served `<head>` |
92
- | XHR navigation | JSON (the normal path) | N/Aonly the first-page document |
92
+ | XHR navigation | JSON (the normal path) | JSON — the same page object |
93
93
 
94
- For XHR navigations (`X-Inertia: true`), keep using `inertia()` — streaming only
95
- benefits the initial HTML document load.
94
+ **Both implement the whole protocol.** An `X-Inertia: true` request gets the page
95
+ object as JSON from either one; the streaming half applies to the first arrival,
96
+ which is the only load that renders a document.
97
+
98
+ That means a route can be moved to `inertiaStream()` for its cold load without
99
+ anything else changing. Until 1.13.2 it could not: `inertiaStream()` answered every
100
+ request with `text/html`, including the XHR, so pointing a route at it broke
101
+ client-side navigation _to_ that route. The first load looked perfect — which is what
102
+ a person checks — and the second click did nothing, for somebody already in the app.
103
+ Apps that hit this wrote a header check in front of the call; that workaround still
104
+ works and is no longer needed.
96
105
 
97
106
  > **Tip** — Stream the heaviest landing pages and leave everything else on `inertia()`.
107
+ > Streaming costs TTFB on a page that is mostly shell, so it is a choice per route
108
+ > rather than a global default.
98
109
 
99
110
  ## Page metadata: `<Head>` on the server
100
111
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zerotal/arch",
3
- "version": "1.13.1",
3
+ "version": "1.13.2",
4
4
  "license": "MIT",
5
5
  "maturity": "stable",
6
6
  "private": false,
@@ -35,11 +35,11 @@
35
35
  "typecheck": "tsc --noEmit"
36
36
  },
37
37
  "dependencies": {
38
- "@zerotal/core": "1.13.1"
38
+ "@zerotal/core": "1.13.2"
39
39
  },
40
40
  "devDependencies": {
41
41
  "typescript": "^5.8.0",
42
- "@zerotal/orm": "1.13.1"
42
+ "@zerotal/orm": "1.13.2"
43
43
  },
44
44
  "description": "The Zerotal agent surface — an MCP server that hands coding agents the framework's machine-readable truth: exact API signatures, live routes and schema, version-matched docs, and `zt doctor`.",
45
45
  "keywords": [