# `assets` _(no submodules)_ ## Purpose Bundled static-asset registry for the GraphiQL UI plugin. The HTML shell references two assets (`graphiql.js`, `graphiql.css`) via hashed filenames under `/assets/`. Hash bytes come from FNV-1a-32 of the asset content — non-cryptographic, used purely for cache-busting on deploy. The asset payloads are shipped inline as TypeScript template strings so the package has zero filesystem requirements at runtime. Operators who want a richer GraphiQL distribution (the full React app) can swap `GRAPHIQL_ASSETS` content on a fork without touching the rest of the plugin. ## Features - `GRAPHIQL_ASSETS` — frozen `Map` exposing every shipped static. - `hashedAssetPath(name)` — builds `..` for embedding in the HTML shell. - `resolveAsset(filename)` — server-side lookup. Tolerates stale hashes during rolling deploys (resolves any matching stem+ext to the current asset). - `fnv1a32(input)` — public so callers can hash their own additions in consistent shape. ## Usage: Basic ```ts import { GRAPHIQL_ASSETS, resolveAsset } from "@suaveplan/api-graphql-ui-graphiql"; for (const asset of GRAPHIQL_ASSETS.values()) { console.log(asset.name, asset.hash, asset.contentType); } const css = resolveAsset("graphiql.css"); ``` ## Usage: Advanced ```ts import { fnv1a32, hashedAssetPath, resolveAsset } from "@suaveplan/api-graphql-ui-graphiql"; // Build the served filename for the JS asset. const path = `/graphql/ui/assets/${hashedAssetPath("graphiql.js")}`; // Verify integrity in a custom asset middleware. const asset = resolveAsset("graphiql.js"); if (fnv1a32(asset.content) !== asset.hash) { throw new Error("asset content drift"); } ``` ## API Reference - `interface GraphiqlAsset { name, content, contentType, hash }`. - `GRAPHIQL_ASSETS: ReadonlyMap`. - `fnv1a32(input: string): string` — 8-char lowercase hex hash. - `hashedAssetPath(name: string): string` — throws `ASSET_MISSING` if `name` is not registered. - `resolveAsset(filename: string): GraphiqlAsset` — throws `ASSET_MISSING` on lookup failure. ## Implementation Notes The stale-hash tolerance is intentional. Picture a CDN-cached `index.html` served before a deploy with the new asset bundle — that `index.html` references `graphiql..js`. Returning 404 on the old hash would break the in-flight session for ~CDN-TTL seconds. The resolver instead serves the new bytes under the old name, traded against a slightly larger attack surface (an adversary who knows the asset name+ext can fetch the asset at any hash). The Cache-Control header on the response is `immutable` for the matched name, so the browser still caches the content correctly.