Skip to content

Releases: davidwhitney/AstroSharp

v0.0.3

Choose a tag to compare

@davidwhitney davidwhitney released this 14 Aug 10:05
5a9c796

Fixes two faults in how a C# page is composed with the page Astro builds around it. Both affected
pages that ship to production, so upgrading is recommended.

npm install astrosharp@0.0.3

A page that renders its own document lost its head content

A .razor page with no [AstroLayout] renders the whole document itself, and was handed to Astro as
opaque markup with nowhere to put the page's head content. Everything arriving through the head was
dropped silently:

  • the page's own scoped <style> blocks — the built HTML had no stylesheet and no CSS asset was
    emitted at all, leaving an element carrying a scope attribute whose rule existed nowhere
  • Astro's dev client — so the page could not hot-reload

The second explains why the first looked intermittent: with no dev client, a page never learned it
had been fixed, so a change that worked appeared to need a server restart. It did not — the page had
no way to be told.

Such a page now renders Astro's head into the gap where its own document closes </head>, which is
what the .astro compiler emits for exactly this shape. A [AstroPage(Partial = true)] page is
unaffected: a fragment gets no head content, in Astro or here.

Response status and headers now match Astro

A page declaring a layout rendered its C# inside the layout's <slot />, which is after Astro
snapshots the response headers. A header set from C# was applied and then discarded, and the status
went with it — a page asking for 418 answered 200.

The previous behaviour was asserted in the tests and justified as Astro's own rule. It is not: an
.astro page keeps its status and headers whether or not it uses a layout, because frontmatter runs
before the template. A .razor page's @code block is frontmatter, so it now runs in the same
place.

before after Astro
own document — header dropped kept kept
own document — status kept kept kept
with a layout — header dropped kept kept
with a layout — status lost (200) kept (418) kept

A header set by a .razor component is still lost, exactly as it is for an .astro component.
That one really is Astro's rule.

The trade-off, measured

Rendering before the layout means the layout's <head> can no longer be flushed while the page
renders. On a page whose C# takes 1.5 seconds, first byte moves from 3ms to 1505ms.

This is the same thing Astro does when the slow work is in frontmatter — measured at 1511ms — and a
.razor page's @code block is frontmatter. The page body never streamed in either version: it is
one round trip to the .NET host. What is lost is only the early head flush, and only for pages doing
slow work in C#.

Gating eager rendering on whether a page touches Astro.Response would recover the flush for pages
that do not. It is not in this release.

Testing

The new assertions were checked against the fault rather than assumed: reverting the change turns
exactly those tests red and nothing else. They include the ordering of the two calls in the generated
module, because that ordering is the behaviour and it is invisible in the rendered HTML.

v0.0.2

Choose a tag to compare

@davidwhitney davidwhitney released this 13 Aug 09:44
858529f

Fixes three faults in 0.0.1 that affected every install. Upgrading is recommended.

npm install astrosharp@0.0.2

Fixed

Vite warned about a missing sourcemap for every module. The published .js files each ended
with a //# sourceMappingURL comment while the .map files were deliberately excluded from the
package, so Vite went looking for files that were not there — 46 warnings on a hello-world build.
Sourcemap generation is off, so the reference is gone along with the file.

// @ts-check in astro.config.mjs reported a wall of TS2322. The integration declared its own
copies of Astro's hook parameter types, and one of them demanded an index signature that Astro's
AstroConfig does not have. Because hook parameters are contravariant, that made the whole
integration unassignable to AstroIntegration. The types are now derived from Astro's own
AstroIntegration rather than copied, so they resolve against whichever Astro you have installed
and cannot drift from it.

npm audit reported a critical vulnerability via astrosharp. The WASI toolchain
(@bytecodealliance/jco) was a hard dependency for the experimental wasm render mode, which is off
by default — so every install paid roughly 97 MB of node_modules and inherited a critical advisory
through decompress, whether or not it used wasm.

A plain install is now 141 MB instead of 403 MB and reports 0 vulnerabilities.

If you use experimental: { serverRendering: 'wasm' }

The toolchain is now an optional peer dependency, so install it explicitly:

npm install -D @bytecodealliance/jco @bytecodealliance/preview2-shim

Building without it fails immediately with a message naming that command. Nothing else about the
mode has changed. This is the only breaking change in the release, and it affects only that mode.

How these were missed, and what now catches them

Every test in the repository consumed the package through the npm workspace, from source. That
resolves exports but ignores files, never type-checks a consumer's config, and never sees the
dependency tree an install produces — so all three faults were invisible to a green suite.

The package verification step now installs the tarball outside the workspace and additionally:

  • type-checks a // @ts-check astro.config.mjs against the shipped .d.ts, under Astro's own
    strict preset
  • fails if any shipped file points at a sourcemap that is not shipped
  • fails if a plain install pulls the WASI toolchain

All three were confirmed by running them against the published 0.0.1 tarball, where all three fail.

v0.0.1

Choose a tag to compare

@davidwhitney davidwhitney released this 12 Aug 16:48
0f1514e

First published release of AstroSharp — write the coded parts of Astro in C#.

Components and pages in Razor, plus loaders, actions, endpoints and middleware in plain C#, running
against Astro's own routing, content collections, asset pipeline and action handling.

Installing

npm install astrosharp
import { defineConfig } from 'astro/config';
import astrosharp from 'astrosharp';

export default defineConfig({ integrations: [astrosharp()] });

Requires the .NET SDK 10 or newer on your PATH as dotnet, and Node 20 or newer.

What's in it

  • .razor pages and components, with C# .cs files compiled alongside them
  • Content collection loaders, including live collections
  • Actions, with input types reflected into schemas and form/file handling
  • Endpoints, static and dynamic, with getStaticPaths
  • Middleware
  • Scoped <style> blocks lifted through Vite into the document head
  • Generated TypeScript types for component props and collection entries
  • An experimental WASI render mode compiled on the user's machine

Supported Astro versions

Astro 5 and above. The declared peer range is held honest by a CI job that builds fixtures against
an actual Astro 5 on every push, rather than by assertion.

Package size

389 kB packed, 1.1 MB unpacked. The .NET sidecar is three assemblies, all of them AstroSharp's own —
no third-party runtime dependencies ship with it.

Provenance

Published from GitHub Actions with npm provenance, from the exact tarball CI built, installed
outside the workspace and used to build a real site before publishing.