@iterant/site-runtime 3.7.0 → 3.8.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/docs/runtime-contract.md +157 -4
- package/package.json +3 -1
- package/src/config/preset.ts +108 -2
- package/src/fonts/catalog.json +361 -0
- package/src/fonts/catalog.ts +88 -0
- package/src/index.ts +1 -0
- package/src/integrations/dev-server-signals.mjs +392 -0
- package/src/integrations/site-config-watch.mjs +38 -0
- package/src/layouts/LayoutCore.astro +43 -0
- package/src/layouts/layout-core.ts +56 -0
package/docs/runtime-contract.md
CHANGED
|
@@ -50,7 +50,7 @@ runtime and says so.
|
|
|
50
50
|
|
|
51
51
|
<!-- generated: available libraries -->
|
|
52
52
|
|
|
53
|
-
_Generated from package.json by scripts/generate-kit-table.mjs. Runtime 3.
|
|
53
|
+
_Generated from package.json by scripts/generate-kit-table.mjs. Runtime 3.8.0._
|
|
54
54
|
|
|
55
55
|
**Toolchain** (this package owns the version; do NOT declare these):
|
|
56
56
|
|
|
@@ -443,7 +443,8 @@ import { SITE_SHELL } from "@/site-shell";
|
|
|
443
443
|
```
|
|
444
444
|
|
|
445
445
|
Every shell keeps importing `../layouts/Layout.astro` unchanged. The core owns
|
|
446
|
-
the head (charset, viewport, favicon, generator, version meta,
|
|
446
|
+
the head (charset, viewport, favicon, generator, version meta, the web fonts
|
|
447
|
+
named in `SITE_CONFIG.fonts`, SEO, JSON-LD,
|
|
447
448
|
hreflang, the `head` slot), resolves locale-aware chrome and the page entry, and
|
|
448
449
|
renders the brand shell around the page slot with the `chrome`, `navbar`,
|
|
449
450
|
`footer` and `shellId` props. It never imports a stylesheet and never imports chrome
|
|
@@ -543,14 +544,87 @@ export default defineConfig({
|
|
|
543
544
|
});
|
|
544
545
|
```
|
|
545
546
|
|
|
546
|
-
The preset carries the adapter, the integrations (React, sitemap,
|
|
547
|
-
dev-only plugin loader, preview error shell
|
|
547
|
+
The preset carries the adapter, the integrations (React, sitemap, the site-config
|
|
548
|
+
watch, and the dev-only plugin loader, preview error shell, new-file reload and
|
|
549
|
+
dev-server signals), the web fonts, the vite
|
|
548
550
|
tuning, the CSS browser floor, the dev server port and host, and the toolbar
|
|
549
551
|
setting. A diverged repo
|
|
550
552
|
extends rather than ejects: extra integrations and vite plugins append through
|
|
551
553
|
`overrides`, and any other key it needs it writes in its own `defineConfig`
|
|
552
554
|
object after the spread.
|
|
553
555
|
|
|
556
|
+
### Web fonts (3.8.0)
|
|
557
|
+
|
|
558
|
+
A site names its font families once, in `SITE_CONFIG.fonts`, and passes the same
|
|
559
|
+
array to the preset:
|
|
560
|
+
|
|
561
|
+
```js
|
|
562
|
+
import { SITE_CONFIG } from "./src/site-config";
|
|
563
|
+
|
|
564
|
+
export default defineConfig({
|
|
565
|
+
site: "https://example.com",
|
|
566
|
+
...iterantStarter({ fonts: SITE_CONFIG.fonts }),
|
|
567
|
+
});
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
The preset turns each name into an Astro font declaration (Google provider,
|
|
571
|
+
weights 400/500/600/700, both slants, subsets latin and latin-ext), and the
|
|
572
|
+
layout renders Astro's `<Font>` for the same families. Names come from the
|
|
573
|
+
catalog the package ships, `@iterant/site-runtime/fonts` (`FONT_CATALOG`,
|
|
574
|
+
`fontCssVariable`, `findFontFamily`); a name the catalog does not carry is
|
|
575
|
+
skipped on both sides rather than failing the render. A family declared as
|
|
576
|
+
`Playfair Display` is set in CSS as `var(--font-playfair-display)`.
|
|
577
|
+
|
|
578
|
+
**The default set is always declared.** `DEFAULT_FONT_FAMILIES` is eleven
|
|
579
|
+
families: one heading default per face class (`DEFAULT_HEADING_FAMILY_BY_CLASS`,
|
|
580
|
+
covering serif, sans, slab, rounded, condensed, display, handwritten and mono)
|
|
581
|
+
plus three body defaults. `SITE_CONFIG.fonts` ADDS to that set, it does not
|
|
582
|
+
replace it, so the family the platform most often picks is already resolved and
|
|
583
|
+
a pick costs no astro.config edit and no restart.
|
|
584
|
+
|
|
585
|
+
The LAYOUT still renders only what a site names, because every family rendered
|
|
586
|
+
inlines its faces into every page. The one exception is a site that names
|
|
587
|
+
nothing: it renders the eleven default faces, with no preload. A repo's
|
|
588
|
+
`globals.css` is written against the variables, so a stylesheet already saying
|
|
589
|
+
`var(--font-fraunces)` on a site with an empty `fonts` array would otherwise get
|
|
590
|
+
the system stack, silently.
|
|
591
|
+
|
|
592
|
+
**Name the families.** The fallback is a safety net, not a resting state, and it
|
|
593
|
+
is not cheap: measured on the fixture's home page, eleven families inline 320
|
|
594
|
+
`@font-face` rules and **93.6K of CSS into the head of every page**, taking a
|
|
595
|
+
102K page from 8.8K of everything-else. One named family is 32 rules and 9.2K,
|
|
596
|
+
on an 18K page. The faces are only declarations, so the browser downloads a file
|
|
597
|
+
when a glyph needs one, but the bytes are in the HTML either way and no cache
|
|
598
|
+
serves them. The fallback also preloads nothing, because eleven blocking font
|
|
599
|
+
requests on a page that has not said which families it uses is the wrong trade.
|
|
600
|
+
Name the families and the page carries exactly those and preloads them.
|
|
601
|
+
|
|
602
|
+
A family in `SITE_CONFIG.fonts` that `astro.config.mjs` never declared is
|
|
603
|
+
skipped rather than rendered. Astro's `<Font>` throws `FontFamilyNotFound` on a
|
|
604
|
+
CSS variable no family registered, so the layout filters the list through
|
|
605
|
+
`fontData`, Astro's own runtime view of the resolved font config, and warns once
|
|
606
|
+
in dev naming the family. That is the case a repo lands in by upgrading and
|
|
607
|
+
adding `SITE_CONFIG.fonts` without also passing it to `iterantStarter`.
|
|
608
|
+
|
|
609
|
+
Declaring is loading: Astro resolves every declared family at dev boot and
|
|
610
|
+
copies every one of its files into the build output. Measured cold: the eleven
|
|
611
|
+
defaults are 1.2s of resolution and 64 files, 1.6MB, per build; the whole
|
|
612
|
+
89-family catalog is 6.3s and 403 files, 9.7MB. Warm, off the `.astro/fonts`
|
|
613
|
+
cache, the eleven are 5ms. `fonts: "catalog"` declares all 89 for a repo that
|
|
614
|
+
has a reason to.
|
|
615
|
+
|
|
616
|
+
The layout preloads the upright latin face of each named family and nothing
|
|
617
|
+
else. Every face stays in the `@font-face` block, so the browser still fetches a
|
|
618
|
+
slanted or extended-latin one the moment a glyph needs it.
|
|
619
|
+
|
|
620
|
+
**`src/site-config.ts` is watched.** Astro restarts its dev server on its own
|
|
621
|
+
config file, `package.json` and the tsconfig sources, and on nothing else, so a
|
|
622
|
+
family added to `SITE_CONFIG.fonts` would be rendered by the layout while Astro
|
|
623
|
+
had never resolved it. The preset adds the file to `settings.watchFiles`
|
|
624
|
+
(`site-config-watch`), which makes the change restart the server and reach the
|
|
625
|
+
font declarations. A repo that keeps its site config elsewhere passes
|
|
626
|
+
`iterantStarter({ siteConfigPath })`.
|
|
627
|
+
|
|
554
628
|
### The browser floor
|
|
555
629
|
|
|
556
630
|
The preset declares the browsers every brand site's CSS is compiled for, to
|
|
@@ -567,6 +641,85 @@ conversation: lowering the floor to Safari 15 does restore `min-width` breakpoin
|
|
|
567
641
|
and costs 7.5K of fallbacks on the template's own sheet, for engines that still
|
|
568
642
|
cannot render its `@property` and `color-mix()` values.
|
|
569
643
|
|
|
644
|
+
### The dev server's signals (3.8.0)
|
|
645
|
+
|
|
646
|
+
Astro restarts its Vite server IN PLACE when a file it watches changes, and the
|
|
647
|
+
repo's `package.json` is one of them: a `bun add` mid-session replaces the whole
|
|
648
|
+
dev server. The content layer is initialised once, at boot, against the first
|
|
649
|
+
server's file watcher, and the restart never re-inits it. Page entries and
|
|
650
|
+
`chrome.json` therefore stop reloading after a restart while `.tsx`, `.astro`
|
|
651
|
+
and `.css` edits keep hot-reloading, and only a process restart clears it.
|
|
652
|
+
|
|
653
|
+
That restart is not rare: the preset watches `src/site-config.ts` too, so every
|
|
654
|
+
change to a site's font list takes this path.
|
|
655
|
+
|
|
656
|
+
The `dev-server-signals` integration closes that gap and reports what happened.
|
|
657
|
+
On a RESTARTED server it watches `src/content/` itself and drives Astro's own
|
|
658
|
+
`refreshContent()`, debounced 100ms so a burst of entry writes syncs once. On the
|
|
659
|
+
boot server it arms nothing: that server's content layer is live and runs its own
|
|
660
|
+
incremental update, and a second full sync per save would buy nothing.
|
|
661
|
+
|
|
662
|
+
It also runs one sync the moment it arms, because a write that landed between
|
|
663
|
+
the old watcher's close and the new one's arm produced an event nobody heard and
|
|
664
|
+
no later event names that file.
|
|
665
|
+
|
|
666
|
+
That first sync has a side effect worth knowing about. Astro's glob loader ends
|
|
667
|
+
its load by calling `add()` on whatever file watcher the content layer holds,
|
|
668
|
+
and chokidar's `add()` reopens a closed watcher, so the refresh brings the dead
|
|
669
|
+
watcher back and the content layer resumes its own per-file updates from the
|
|
670
|
+
second edit onward. Measured on the consumer fixture across three restarts: the
|
|
671
|
+
revived watcher comes back holding 3 dirs and 6 paths, the collection dirs only,
|
|
672
|
+
against the live watcher's 41 and 123; only that one watcher ever revives, so
|
|
673
|
+
there are at most two alive whatever the restart count; and every content edit
|
|
674
|
+
after the first then costs one extra full sync, 7.7ms median over four entries,
|
|
675
|
+
alongside the layer's own single-file update. The arm stays as it is: the layer
|
|
676
|
+
heals BECAUSE of it (nothing else calls `add()`, and the first edit after a
|
|
677
|
+
restart is carried by the arm alone), and the duplicate is a few milliseconds
|
|
678
|
+
rather than a second watcher over the whole tree.
|
|
679
|
+
|
|
680
|
+
It writes one line of JSON per event on stdout, every one keyed `iterant` so a
|
|
681
|
+
supervisor reading the dev log can filter them:
|
|
682
|
+
|
|
683
|
+
```
|
|
684
|
+
{"iterant":"dev-server","event":"restart","phase":"config"}
|
|
685
|
+
{"iterant":"dev-server","event":"restart","phase":"setup"}
|
|
686
|
+
{"iterant":"dev-server","event":"ready","restart":true}
|
|
687
|
+
{"iterant":"dev-server","event":"content-synced","restart":true,"paths":["src/content/pages/home.json"]}
|
|
688
|
+
{"iterant":"dev-server","event":"content-sync-failed","restart":true,"paths":[...],"error":"..."}
|
|
689
|
+
```
|
|
690
|
+
|
|
691
|
+
`ready` goes out when the server's socket starts listening, which is the first
|
|
692
|
+
moment those routes can be reached. The same news reaches clients over Vite's
|
|
693
|
+
HMR channel as `iterant:server-ready` (`{ restart, at }`), sent as each client
|
|
694
|
+
connects rather than at startup, because a payload sent before a client attaches
|
|
695
|
+
is dropped; `iterant:content-synced` (`{ paths, at }`) follows each sync. There
|
|
696
|
+
is no "restarting" event: the old server is gone before any hook on the new one
|
|
697
|
+
runs, so the arrival is the only half that can be sent.
|
|
698
|
+
|
|
699
|
+
Two dev-only routes report and force the state. They exist on the dev server and
|
|
700
|
+
in no build:
|
|
701
|
+
|
|
702
|
+
| Route | Answers |
|
|
703
|
+
| -------------------------- | ---------------------------------------------------------------------------- |
|
|
704
|
+
| `GET /__iterant/dev-state` | `{ restart, startedAt, contentSync: { armed, lastAt, lastPaths }, entries }` |
|
|
705
|
+
| `POST /__iterant/refresh` | `{ ok: true, at }`, or 500 `{ ok: false, error }` if the sync rejects |
|
|
706
|
+
|
|
707
|
+
Both require the request header `x-iterant-dev-state: 1`, which the preview
|
|
708
|
+
supervisor sends. Without it the request falls through to Astro and is answered
|
|
709
|
+
exactly as it would be if the integration were not installed: 404 for the GET,
|
|
710
|
+
Astro's own cross-site rejection for the POST. The dev server binds to a host
|
|
711
|
+
the preview tunnel can reach, so a route that answered any caller would be a
|
|
712
|
+
content-refresh trigger anyone with the URL could pull.
|
|
713
|
+
|
|
714
|
+
`entries` is a sha256 per `.json` file in the content dirs the collections read
|
|
715
|
+
(`pagesDir` and `chromeDir`, whatever a repo set them to), keyed by path from the
|
|
716
|
+
project root (`src/content/pages/home.json`). It is the files on DISK, not what
|
|
717
|
+
the content layer holds: the store is reachable only through Astro internals an
|
|
718
|
+
integration must not import. A writer compares the digest it expects against the
|
|
719
|
+
one reported, and calls `POST /__iterant/refresh` if the layer is behind. Every
|
|
720
|
+
timestamp in these payloads, and in the signal lines, is an ISO 8601 string in
|
|
721
|
+
UTC, never an epoch number.
|
|
722
|
+
|
|
570
723
|
## Verify: the gate
|
|
571
724
|
|
|
572
725
|
`bun run verify` maps to `site-runtime verify` and is the gate. It is silent on
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@iterant/site-runtime",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.8.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "The platform layer every Iterant brand site runs on: content grammar, collection schemas, SEO head and JSON-LD, layout core, Astro config preset, dev integrations and the verify gates.",
|
|
6
6
|
"scripts": {
|
|
@@ -44,6 +44,8 @@
|
|
|
44
44
|
"./locales": "./src/lib/locales.ts",
|
|
45
45
|
"./hreflang": "./src/lib/hreflang.ts",
|
|
46
46
|
"./chrome": "./src/lib/chrome.ts",
|
|
47
|
+
"./fonts": "./src/fonts/catalog.ts",
|
|
48
|
+
"./fonts/catalog.json": "./src/fonts/catalog.json",
|
|
47
49
|
"./chrome-schemas": "./src/lib/chrome-schemas.ts",
|
|
48
50
|
"./bespoke-pages": "./src/lib/bespoke-pages.ts",
|
|
49
51
|
"./sitemap": "./src/lib/sitemap/index.ts",
|
package/src/config/preset.ts
CHANGED
|
@@ -4,11 +4,20 @@ import cloudflare from "@astrojs/cloudflare";
|
|
|
4
4
|
import react from "@astrojs/react";
|
|
5
5
|
import tailwindcss from "@tailwindcss/vite";
|
|
6
6
|
import type { AstroUserConfig } from "astro";
|
|
7
|
-
import { sessionDrivers } from "astro/config";
|
|
7
|
+
import { fontProviders, sessionDrivers } from "astro/config";
|
|
8
8
|
|
|
9
|
+
import {
|
|
10
|
+
DEFAULT_FONT_FAMILIES,
|
|
11
|
+
FONT_CATALOG,
|
|
12
|
+
fontCssVariable,
|
|
13
|
+
findFontFamily,
|
|
14
|
+
} from "../fonts/catalog";
|
|
15
|
+
import { DEFAULT_CHROME_DIR, DEFAULT_PAGES_DIR } from "../lib/content-paths";
|
|
16
|
+
import devServerSignals from "../integrations/dev-server-signals.mjs";
|
|
9
17
|
import iterantPlugins from "../integrations/iterant-plugins.mjs";
|
|
10
18
|
import newFileReload from "../integrations/new-file-reload.mjs";
|
|
11
19
|
import previewErrorShell from "../integrations/preview-error-shell.mjs";
|
|
20
|
+
import siteConfigWatch from "../integrations/site-config-watch.mjs";
|
|
12
21
|
import { sitemapWithCustomPages } from "../lib/sitemap";
|
|
13
22
|
|
|
14
23
|
/**
|
|
@@ -37,6 +46,71 @@ import { sitemapWithCustomPages } from "../lib/sitemap";
|
|
|
37
46
|
*/
|
|
38
47
|
const CSS_TARGET = ["safari16.4", "chrome111", "firefox128", "edge111"];
|
|
39
48
|
|
|
49
|
+
/** Astro's font schema takes the three below as non-empty tuples, not arrays. */
|
|
50
|
+
type NonEmpty<T> = [T, ...T[]];
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* The weights and styles every catalog family is requested at.
|
|
54
|
+
*
|
|
55
|
+
* FOUR EXPLICIT WEIGHTS, not a variable range. Unifont's google provider decides
|
|
56
|
+
* variable-versus-static per family (`prepareWeights`, on the family's own
|
|
57
|
+
* `wght` axis), and it forwards a range straight into the css2 URL: `100 900`
|
|
58
|
+
* against a family whose axis is narrower (EB Garamond is 400..800) comes back
|
|
59
|
+
* 400 Bad Request, and `throwOnError: false` turns that into a family that
|
|
60
|
+
* silently resolves to zero faces. Measured on the whole catalog: the range
|
|
61
|
+
* lost 37 of 89 families, these four weights resolve all 89. Where the family
|
|
62
|
+
* IS variable, Google still serves one variable file per subset, so asking for
|
|
63
|
+
* four weights costs four faces and one download, not four.
|
|
64
|
+
*
|
|
65
|
+
* Astro's own defaults are one weight and both slants; both are restated here
|
|
66
|
+
* because the catalog's value is that any family in it renders the same way.
|
|
67
|
+
*/
|
|
68
|
+
const FONT_WEIGHTS: NonEmpty<string> = ["400", "500", "600", "700"];
|
|
69
|
+
const FONT_STYLES: NonEmpty<"normal" | "italic"> = ["normal", "italic"];
|
|
70
|
+
const FONT_SUBSETS: NonEmpty<string> = ["latin", "latin-ext"];
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* The default set plus whatever the site names, as Astro font declarations.
|
|
74
|
+
*
|
|
75
|
+
* DECLARING IS LOADING, which is why this is a set and not the whole catalog.
|
|
76
|
+
* Astro's fonts plugin resolves every declared family in `buildStart`,
|
|
77
|
+
* sequentially, once per dev server and once per build, and `buildEnd` writes
|
|
78
|
+
* every file of every declared family into the client output. Measured cold:
|
|
79
|
+
* the eleven defaults cost 1.2s at dev boot (829ms of resolution, ~75ms a
|
|
80
|
+
* family, plus 338ms of provider init) and 64 font files, 1.6MB, into `dist/`
|
|
81
|
+
* per build. The whole 89-family catalog costs 6.3s and 403 files, 9.7MB.
|
|
82
|
+
* Warm (the `.astro/fonts` cache, or `node_modules/.astro/fonts` for a build)
|
|
83
|
+
* eleven families are 5ms, but a preview sandbox clones the repo fresh, so it
|
|
84
|
+
* pays the cold number on its first boot.
|
|
85
|
+
*
|
|
86
|
+
* The defaults are declared unconditionally because the alternative is worse
|
|
87
|
+
* than a second of boot: the platform picks a family from the catalog, writes
|
|
88
|
+
* it into SITE_CONFIG.fonts, and until the dev server restarts the layout would
|
|
89
|
+
* render a face Astro never resolved. `site-config-watch` makes that restart
|
|
90
|
+
* happen, and these eleven make it unnecessary for the common pick.
|
|
91
|
+
*
|
|
92
|
+
* A name the catalog does not carry is skipped rather than declared: Astro's
|
|
93
|
+
* `<Font>` throws on a CSS variable no family registered, and the layout reads
|
|
94
|
+
* the same catalog to decide what to render.
|
|
95
|
+
*/
|
|
96
|
+
function catalogFontFamilies(fonts: readonly string[] | "catalog") {
|
|
97
|
+
const names =
|
|
98
|
+
fonts === "catalog"
|
|
99
|
+
? FONT_CATALOG.map((entry) => entry.family)
|
|
100
|
+
: [...DEFAULT_FONT_FAMILIES, ...fonts];
|
|
101
|
+
const families = [...new Set(names)]
|
|
102
|
+
.map((family) => findFontFamily(family))
|
|
103
|
+
.filter((entry) => entry !== undefined);
|
|
104
|
+
return families.map((entry) => ({
|
|
105
|
+
name: entry.family,
|
|
106
|
+
cssVariable: fontCssVariable(entry.family),
|
|
107
|
+
provider: fontProviders.google(),
|
|
108
|
+
weights: FONT_WEIGHTS,
|
|
109
|
+
styles: FONT_STYLES,
|
|
110
|
+
subsets: FONT_SUBSETS,
|
|
111
|
+
}));
|
|
112
|
+
}
|
|
113
|
+
|
|
40
114
|
// The Astro configuration every brand site runs on, as one spreadable fragment:
|
|
41
115
|
//
|
|
42
116
|
// // astro.config.mjs
|
|
@@ -72,6 +146,28 @@ export interface IterantStarterOptions {
|
|
|
72
146
|
* knob, so the sitemap and the collection can never read different dirs.
|
|
73
147
|
*/
|
|
74
148
|
pagesDir?: string;
|
|
149
|
+
/**
|
|
150
|
+
* Directory holding chrome.json, its locale siblings and links.json, if a
|
|
151
|
+
* repo moved it. Same rule as `pagesDir`: `createCollections` takes the same
|
|
152
|
+
* value, and the dev server's content re-arm watches whichever pair is set,
|
|
153
|
+
* so a relocated tree is repaired and reported like any other.
|
|
154
|
+
*/
|
|
155
|
+
chromeDir?: string;
|
|
156
|
+
/**
|
|
157
|
+
* Font families this site uses, by catalog name (`["Fraunces", "Inter"]`).
|
|
158
|
+
* The same list the layout receives as `siteConfig.fonts`, so a repo passes
|
|
159
|
+
* its `SITE_CONFIG.fonts` here and the two cannot name different families.
|
|
160
|
+
* ADDED to the default set rather than replacing it; omitted or empty leaves
|
|
161
|
+
* the defaults alone. `"catalog"` declares all 89, at the cost
|
|
162
|
+
* `catalogFontFamilies` measures.
|
|
163
|
+
*/
|
|
164
|
+
fonts?: readonly string[] | "catalog";
|
|
165
|
+
/**
|
|
166
|
+
* The repo's site config module, relative to the project root. Watched, so a
|
|
167
|
+
* change to `SITE_CONFIG.fonts` restarts the dev server and reaches the font
|
|
168
|
+
* declarations; the preset does not import the file, it only names it.
|
|
169
|
+
*/
|
|
170
|
+
siteConfigPath?: string;
|
|
75
171
|
/**
|
|
76
172
|
* Extensions for a diverged repo. These are the two keys a spread cannot
|
|
77
173
|
* express: extra `integrations` APPEND after the platform's, and `vite`
|
|
@@ -93,7 +189,10 @@ export interface IterantStarterOptions {
|
|
|
93
189
|
export function iterantStarter({
|
|
94
190
|
site,
|
|
95
191
|
allowedHosts = true,
|
|
96
|
-
pagesDir,
|
|
192
|
+
pagesDir = DEFAULT_PAGES_DIR,
|
|
193
|
+
chromeDir = DEFAULT_CHROME_DIR,
|
|
194
|
+
fonts = [],
|
|
195
|
+
siteConfigPath = "src/site-config.ts",
|
|
97
196
|
overrides,
|
|
98
197
|
}: IterantStarterOptions = {}) {
|
|
99
198
|
// A repo's own wrangler config, when it has one. The template checks in a
|
|
@@ -125,8 +224,14 @@ export function iterantStarter({
|
|
|
125
224
|
previewErrorShell(),
|
|
126
225
|
// Dev-only: broadcast a reload when a new src/ file matches no module.
|
|
127
226
|
newFileReload(),
|
|
227
|
+
// Dev-only: restart signals, the content re-arm, and the dev-state probe.
|
|
228
|
+
devServerSignals({ pagesDir, chromeDir }),
|
|
229
|
+
// Restart the dev server when the site config the fonts come from changes.
|
|
230
|
+
siteConfigWatch(siteConfigPath),
|
|
128
231
|
];
|
|
129
232
|
|
|
233
|
+
const fontFamilies = catalogFontFamilies(fonts);
|
|
234
|
+
|
|
130
235
|
const vite: NonNullable<AstroUserConfig["vite"]> = {
|
|
131
236
|
cacheDir: viteCacheDir,
|
|
132
237
|
plugins: [tailwindcss()],
|
|
@@ -215,6 +320,7 @@ export function iterantStarter({
|
|
|
215
320
|
// allow a package MINOR to make; the runtime therefore keeps the old
|
|
216
321
|
// behavior and a later MAJOR can adopt "jsx" deliberately.
|
|
217
322
|
compressHTML: true,
|
|
323
|
+
fonts: fontFamilies,
|
|
218
324
|
integrations,
|
|
219
325
|
vite,
|
|
220
326
|
// Port 4321 (Astro's default), NOT 3000: inside a Cloudflare Sandbox port
|