Repository navigation
feat(examples): csr-react + baked-assets recipe; fix header() missing-key fence (issue #10) - #93
Merged
Conversation
A bare this._headers[key] read throws "record has no key" under program-code (single-graph/vendored) scriptc compilation — the typed record slot cannot represent undefined — while packed-dist compilation tolerates the read. Any optional request header (if-none-match, accept-encoding, accept) therefore fenced compiled apps that read headers through vendored sources; packed consumers were unaffected. Guard both the _headers and _headersDistinct lookups with Object.prototype.hasOwnProperty.call, the same idiom ReqView already uses for optional fields. Verified: a vendored @chttp/router + @chttp/static graph now serves 200/304 where it previously aborted.
… recipe (issue #10) Adds examples/integrations/csr-react: a Vite-built React SPA served by serveStatic({ spa: true }) with an /api slice on the same router, plus the JSON-baked assets recipe — scripts/bake.mjs walks dist/ and emits an EmbeddedAssets subclass (BakedAssets) for the single-binary path, and scripts/vendor.mjs stages one program-code graph (the same pattern as ws-echo) so scriptc lowers the subclass. docs/static.md gains "Baking assets into the binary" documenting the recipe and the case-6 (JSON b64) vs case-9 (FFI blob) tradeoffs from the frontend probes; docs/context.md documents c.bytes. Node tests cover the honesty gates: sha256 byte-integrity of a hashed asset, ETag -> 304 with empty body, SPA Accept rules, /api JSON 404, and the same assertions against the baked source. ELF smoke verified manually under scriptc 0.3.6: 100% static coverage, byte-identical asset, 304 revalidation, SPA fallback.
Contributor
|
I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".
|
Deploying chttpjs with
|
| Latest commit: |
0aa9aae
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://8dffa566.chttpjs.pages.dev |
| Branch Preview URL: | https://devin-1792395888-csr-serving.chttpjs.pages.dev |
CI's pnpm -r build invokes the package's build directly; bake needs dist/ to exist.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Issue #10 — the CSR serving slice. Most of the surface already existed (
c.bytes,@chttp/staticwith sha1 ETag/304, hand-rolledhttpDate); this PR lands the two missing pieces and fixes one compiler-mode bug the example exposed.examples/integrations/csr-react— a Vite-built React SPA served byserveStatic(app, "/", src, { spa: true })with an/api/helloroute on the same router. Two asset modes sharing onebuildApp(src: AssetSource):src/main.ts:DiskAssets("./dist")— dev/plain-node, re-reads on mtime+size change.src/main.baked.ts:BakedAssets— the JSON-baked assets recipe.scripts/bake.mjswalksdist/and emitssrc/assets.gen.ts, anEmbeddedAssetssubclass whose constructor callsload(records)(array ofEmbedRecord, never a path-keyed object).scripts/vendor.mjsstages.vendor/the same way ws-echo does —BakedAssetssubclasses a package class, so scriptc needs the whole graph as program code.pnpm build= bake + vendor +scriptc build→ single binary, no filesystem.fix(router)—ReqViewCore.header()readthis._headers[key]andthis._headersDistinct[key]bare. Under program-code compilation a missing typed-record key throws"record has no key"(the process aborts on the first request); packed-dist compilation tolerates it, so the bug only shows in vendored builds. Any optional request header lookup (if-none-match,accept-encoding,accept) fenced the whole app —@chttp/staticin a vendored ELF crashed serving anything. Both reads now probe withObject.prototype.hasOwnProperty.call, the idiom already used elsewhere inReqView. Changeset included (patch).Docs —
docs/static.mdgains "Baking assets into the binary": the recipe plus the case-6 (JSON b64: +365 KB binary, ~0.15 ms decode) vs case-9 (FFI blob: +303 KB, ~0.055 ms copy,cc+ffi.jsontoolchain) tradeoffs frombench/scriptc-evidence/frontend-probes-2026-10-14.txt.docs/context.mddocumentsc.bytes;docs/examples.md+examples/README.mdindex the example.Verification
pnpm --filter chttp-example-csr-react test: 6 node tests — sha256 byte-identity of the hashed Vite asset, ETag→304 with empty body, SPAAccept: text/htmlfallback + extensioned-miss 404,/apiJSON 404, and the same assertions againstBakedAssets.scriptc coverage src/main.baked.ts= 1713/1713 (100%); the built binary serves/, the hashed JS byte-identical (sha256 match), 304 on revalidation, SPA fallback,/api/hello, and 404s — all verified by curl.pnpm --filter @chttp/router test: 93 pass incl. its ownelf.test.sh;pnpm --filter @chttp/static test: 24 pass.scripts/scriptc-gate.sh: all gates 100% exceptbench/apps/chttp-stream.ts, which fails identically onorigin/main(@chttp/router/src/index.tsunresolvable in the stream package — pre-existing env issue, not this branch).Link to Devin session: https://app.devin.ai/sessions/2e23b2b68f7a464697373e89c206f61f
Open in Devin Desktop: https://app.devin.ai/desktop/session/2e23b2b68f7a464697373e89c206f61f?variant=devin
Requested by: @espetro