# Data flow — Chalarangelo/30-seconds-of-code

> Canonical page: https://codevetter.com/unpack/30-seconds-of-code/data-flow

# Data flow — Chalarangelo/30-seconds-of-code

Scanned commit bd756f8b2283a38560efe83cb30af38324d4e9e9 (2026-09-09). Generated by codevetter codevetter 1.12.0 on 2026-09-22.

Data flows one direction: content/ sources → extraction (FileHandler globs + front-matter/YAML parsing) → per-model workers that render HTML, tokenize, rank, and build join records → .content/content.json → in-memory model graph via Loader reviver → page adapters + serializers → .content/pages/*.json plus public/ artifacts (search-data.json, feed.xml, sitemap.xml, _redirects) → Astro getStaticPaths → static HTML. The browser is a terminal consumer: it fetches search-data.json and rebuilds the same DocumentIndex used at build time. There is no runtime server state; 'state owners' are the static Model registries hydrated once per build/console process.
- Input boundaries are globbed files: content/snippets/**/s/*.md (front-matter + markdown), content/collections/**/*.yaml, content/languages/*.yaml, plus singleton files grammars.yaml, rankingEngine.yaml, hub.yaml — all read through FileHandler.read which dispatches on extension to JSON/YAML/front-matter readers. — [src/lib/contentUtils/config.js](https://github.com/Chalarangelo/30-seconds-of-code/blob/bd756f8b2283a38560efe83cb30af38324d4e9e9/src/lib/contentUtils/config.js) [src/lib/contentUtils/fileHandler.js](https://github.com/Chalarangelo/30-seconds-of-code/blob/bd756f8b2283a38560efe83cb30af38324d4e9e9/src/lib/contentUtils/fileHandler.js)
- extractData is the single orchestration point: it loads languages, grammars, hub, and keyword data; selects Shiki or Prism as codeHighlighter; calls MarkdownParser.setupProcessors and sets Ranker.keywordScores; then extracts snippets, collections, and collectionSnippets in that order. — [src/lib/contentUtils/extractor.js](https://github.com/Chalarangelo/30-seconds-of-code/blob/bd756f8b2283a38560efe83cb30af38324d4e9e9/src/lib/contentUtils/extractor.js)
- Snippet extraction derives id from filePath by stripping the 'content/snippets/' prefix and '.md' suffix, renders excerpt and body to HTML through a per-language MarkdownParser processor, computes recTokens and docTokens via tokenize(), computes a 0-1 ranking via Ranker.rankIndexableContent, and builds tableOfContentsHtml via TocReader when tocEnabled. — [src/lib/contentUtils/modelWorkers/snippet.js](https://github.com/Chalarangelo/30-seconds-of-code/blob/bd756f8b2283a38560efe83cb30af38324d4e9e9/src/lib/contentUtils/modelWorkers/snippet.js) [src/lib/contentUtils/ranker.js](https://github.com/Chalarangelo/30-seconds-of-code/blob/bd756f8b2283a38560efe83cb30af38324d4e9e9/src/lib/contentUtils/ranker.js) [src/lib/contentUtils/tocReader.js](https://github.com/Chalarangelo/30-seconds-of-code/blob/bd756f8b2283a38560efe83cb30af38324d4e9e9/src/lib/contentUtils/tocReader.js)
- MarkdownParser maintains one unified() processor per language short-code plus a 'default'; each processor embeds that language's reference map (merged from allLanguageReferences) for linkInlineCode, so inline-code autolinking is per-language. — [src/lib/contentUtils/markdownParser/markdownParser.js#L29-99](https://github.com/Chalarangelo/30-seconds-of-code/blob/bd756f8b2283a38560efe83cb30af38324d4e9e9/src/lib/contentUtils/markdownParser/markdownParser.js#L29-L99)
- exportXData functions flatten extracted objects into plain records tagged with a 'model' field ('Snippet', 'Collection', 'Language', 'CollectionSnippet'); ContentUtils.prepareContent writes the aggregate to .content/content.json via FileHandler.write. — [src/lib/contentUtils/contentUtils.js#L14-26](https://github.com/Chalarangelo/30-seconds-of-code/blob/bd756f8b2283a38560efe83cb30af38324d4e9e9/src/lib/contentUtils/contentUtils.js#L14-L26) [src/lib/contentUtils/modelWorkers/snippet.js#L98-119](https://github.com/Chalarangelo/30-seconds-of-code/blob/bd756f8b2283a38560efe83cb30af38324d4e9e9/src/lib/contentUtils/modelWorkers/snippet.js#L98-L119)
- CollectionSnippet join records are produced by extractCollectionSnippetData: explicit snippetIds are looked up with a console.warn on missing, matcher-based collections filter ranked snippets by languageKey/tags, the 'snippets' main collection gets position = rank index (-1 for unlisted), and allowUnlisted controls inclusion. — [src/lib/contentUtils/modelWorkers/collectionSnippet.js](https://github.com/Chalarangelo/30-seconds-of-code/blob/bd756f8b2283a38560efe83cb30af38324d4e9e9/src/lib/contentUtils/modelWorkers/collectionSnippet.js)
- On load, every model constructor pushes itself into Model.instances[name] and registers each declared index into Model.indexedInstances[name][index] maps; all Snippet and Collection instances are indexed on 'id'. — [src/core/model.js#L52-63](https://github.com/Chalarangelo/30-seconds-of-code/blob/bd756f8b2283a38560efe83cb30af38324d4e9e9/src/core/model.js#L52-L63) [src/models/snippet.js#L13-16](https://github.com/Chalarangelo/30-seconds-of-code/blob/bd756f8b2283a38560efe83cb30af38324d4e9e9/src/models/snippet.js#L13-L16) [src/models/collection.js#L10-13](https://github.com/Chalarangelo/30-seconds-of-code/blob/bd756f8b2283a38560efe83cb30af38324d4e9e9/src/models/collection.js#L10-L13)
- Page serialization path: AstroContent.generate calls Collection.pages / snippet.page / Page.home, each Page subclass exposes params and props getters, PageSerializer.serialize emits {params, props:{...props, structuredData: schemaData}}, and results are keyed by page.key into JSON files under .content/pages/. — [src/lib/astroContent.js](https://github.com/Chalarangelo/30-seconds-of-code/blob/bd756f8b2283a38560efe83cb30af38324d4e9e9/src/lib/astroContent.js) [src/adapters/page.js#L10-30](https://github.com/Chalarangelo/30-seconds-of-code/blob/bd756f8b2283a38560efe83cb30af38324d4e9e9/src/adapters/page.js#L10-L30) [src/serializers/pageSerializer.js](https://github.com/Chalarangelo/30-seconds-of-code/blob/bd756f8b2283a38560efe83cb30af38324d4e9e9/src/serializers/pageSerializer.js) [src/adapters/page/collectionPage.js#L9-29](https://github.com/Chalarangelo/30-seconds-of-code/blob/bd756f8b2283a38560efe83cb30af38324d4e9e9/src/adapters/page/collectionPage.js#L9-L29)
- Astro routes are pure consumers of generated JSON: [snippet].astro and [...listing].astro implement getStaticPaths by reading the corresponding .content JSON file and mapping entries to {params, props}; index.astro reads index.json synchronously at module scope. — [src/astro/pages/[lang]/s/[snippet].astro#L15-26](https://github.com/Chalarangelo/30-seconds-of-code/blob/bd756f8b2283a38560efe83cb30af38324d4e9e9/src/astro/pages/%5Blang%5D/s/%5Bsnippet%5D.astro#L15-L26) [src/astro/pages/[lang]/[...listing].astro#L11-26](https://github.com/Chalarangelo/30-seconds-of-code/blob/bd756f8b2283a38560efe83cb30af38324d4e9e9/src/astro/pages/%5Blang%5D/%5B...listing%5D.astro#L11-L26) [src/astro/pages/index.astro#L13-14](https://github.com/Chalarangelo/30-seconds-of-code/blob/bd756f8b2283a38560efe83cb30af38324d4e9e9/src/astro/pages/index.astro#L13-L14)
- Search data path: snippet/collection docTokens strings ('token:count' space-joined) are serialized by SearchResultSerializer into public/search-data.json; the browser fetches it, deserializeTokens rebuilds Map<term,freq>, and DocumentIndex re-derives trigram sets for fuzzy matching. — [src/lib/searchIndex.js](https://github.com/Chalarangelo/30-seconds-of-code/blob/bd756f8b2283a38560efe83cb30af38324d4e9e9/src/lib/searchIndex.js) [src/serializers/searchResultSerializer.js](https://github.com/Chalarangelo/30-seconds-of-code/blob/bd756f8b2283a38560efe83cb30af38324d4e9e9/src/serializers/searchResultSerializer.js) [src/astro/scripts/omnisearch.js#L19-34](https://github.com/Chalarangelo/30-seconds-of-code/blob/bd756f8b2283a38560efe83cb30af38324d4e9e9/src/astro/scripts/omnisearch.js#L19-L34) [src/lib/search/utils.js](https://github.com/Chalarangelo/30-seconds-of-code/blob/bd756f8b2283a38560efe83cb30af38324d4e9e9/src/lib/search/utils.js)
- Ranker scores content against the sorted keyword table from content/rankingEngine.yaml, capping at 20 keywords or a score of 100, and returns max(0.0001, score/100) so no snippet ranks exactly 0. — [src/lib/contentUtils/ranker.js](https://github.com/Chalarangelo/30-seconds-of-code/blob/bd756f8b2283a38560efe83cb30af38324d4e9e9/src/lib/contentUtils/ranker.js) [content/rankingEngine.yaml](https://github.com/Chalarangelo/30-seconds-of-code/blob/bd756f8b2283a38560efe83cb30af38324d4e9e9/content/rankingEngine.yaml)
- Redirects flow: content/redirects.yaml is loaded once in a static block, Redirects.generate writes 'from to status' lines to public/_redirects, and Redirects.for(slug) does a transitive lookup used by ContentModel.allSlugs for canonical/alias handling. — [src/lib/redirects.js](https://github.com/Chalarangelo/30-seconds-of-code/blob/bd756f8b2283a38560efe83cb30af38324d4e9e9/src/lib/redirects.js) [src/models/contentModel.js#L58-60](https://github.com/Chalarangelo/30-seconds-of-code/blob/bd756f8b2283a38560efe83cb30af38324d4e9e9/src/models/contentModel.js#L58-L60) [content/redirects.yaml](https://github.com/Chalarangelo/30-seconds-of-code/blob/bd756f8b2283a38560efe83cb30af38324d4e9e9/content/redirects.yaml)
- TimestampDump.generate writes a hex timestamp to src/astro/timestamp.js, which Layout.astro injects via define:vars into an empty script solely to force HMR when content regenerates during watch mode. — [src/lib/timestampDump.js](https://github.com/Chalarangelo/30-seconds-of-code/blob/bd756f8b2283a38560efe83cb30af38324d4e9e9/src/lib/timestampDump.js) [src/astro/layouts/Layout.astro#L9-34](https://github.com/Chalarangelo/30-seconds-of-code/blob/bd756f8b2283a38560efe83cb30af38324d4e9e9/src/astro/layouts/Layout.astro#L9-L34)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
