diff --git a/Packages/Infrastructure/README.md b/Packages/Infrastructure/README.md index b724c15..dfc8bd7 100644 --- a/Packages/Infrastructure/README.md +++ b/Packages/Infrastructure/README.md @@ -10,13 +10,15 @@ The package provides, grouped by role: | Pages and assets | `Page`, `Asset`, `AssetExtension`, `FingerprintAssets` | | Link previews | `SocialCard`, its `Image`, and the `Tag` meta tags it derives | | Structured data | `StructuredData`, the `Node`, `Property`, and `Value` types of its schema.org graph, and the open `Name` and `Kind` vocabularies | +| Analytics | `Analytics`, the tracker script `Attribute`s it derives, and the `origin` its preconnect hint targets | | Responses | `CachedHTMLResponse`, `LocalizedHTMLCollectionResponse` | | Contexts | `LocalizedRequestContext` | | Constants | The `HTTPField.Name` header names, `Int.RateLimit` limits, and `String.Security` header values the middlewares default to | ## Design rules The package holds only what every service can reuse; anything a service owns is injected, never referenced: -- **No site-specific content.** No page markup, no asset catalog, no `Bundle.module` lookups. A type that needs a service's content takes it as a parameter: the `bundle:` whose String Catalog names the supported languages (`LocalizationMiddleware`, `LocalizedHTMLCollectionResponse`, `NotFoundMiddleware`), the `document:` closure that builds a page for a locale, and the `metadata` requirement through which a `Page` conformer supplies its icon links and theme colors — as are the `summary`, `canonicalURL`, `socialCard`, and `structuredData` values its other head tags render, each omitted unless the page provides it. A `SocialCard` and a `StructuredData` node take their URLs fully formed and absolute; composing them from an origin and a versioned asset path stays with the page providing them. +- **No site-specific content.** No page markup, no asset catalog, no `Bundle.module` lookups. A type that needs a service's content takes it as a parameter: the `bundle:` whose String Catalog names the supported languages (`LocalizationMiddleware`, `LocalizedHTMLCollectionResponse`, `NotFoundMiddleware`), the `document:` closure that builds a page for a locale, and the `metadata` requirement through which a `Page` conformer supplies its icon links and theme colors — as are the `summary`, `canonicalURL`, `socialCard`, `structuredData`, and `analytics` values its other head tags render, each omitted unless the page provides it. A `SocialCard` and a `StructuredData` node take their URLs fully formed and absolute, as does an `Analytics` its script URL; composing them from an origin and a versioned asset path stays with the page providing them. +- **Types own their format; `Page` renders generically.** Each optional head concern derives its own render-ready representation — the `SocialCard.tags` meta tags, the `StructuredData.payload` JSON-LD, the `Analytics.attributes` script attributes — and the `Page` scaffolding applies it without knowing the vocabulary (Open Graph, schema.org, or the Umami tracker convention). The page ``scripts`` and the analytics tracker render as `defer`red head tags, with a `preconnect` hint for the tracker's cross-origin host. - **Services fill the gaps once, via extensions.** A service restores its convenient call sites with retroactive extensions — the Website's `Page+Defaults`, `LocalizationMiddleware+Defaults`, and `NotFoundMiddleware+Defaults` are the pattern to follow. The open schema.org vocabularies extend the same way: the package declares only the `Property.Name` and `Node.Kind` constants every service shares, and a service adds the ones its own node shapes need. - **Method structs.** Single-operation types such as `FingerprintAssets` hold their lifetime-fixed configuration in `init` and take only per-call inputs in `callAsFunction`. @@ -32,7 +34,7 @@ Sources/ │ ├── Middlewares/ the five HTTP middlewares │ ├── Protocols/ Asset, LocalizedRequestContext, Page, RouterController │ ├── Responses/ CachedHTMLResponse, LocalizedHTMLCollectionResponse -│ └── Types/ SocialCard and StructuredData, with their nested types in SocialCard/ and StructuredData/ +│ └── Types/ Analytics, SocialCard, and StructuredData, the latter two with their nested types in SocialCard/ and StructuredData/ └── Internal/ ├── Extensions/ implementation details (the String separators) └── Types/ implementation details (FNV1aHash)