@refrakt-md/runes 0.14.4 → 0.16.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.
Files changed (119) hide show
  1. package/dist/aggregate-resolve.d.ts +4 -0
  2. package/dist/aggregate-resolve.d.ts.map +1 -0
  3. package/dist/aggregate-resolve.js +209 -0
  4. package/dist/aggregate-resolve.js.map +1 -0
  5. package/dist/collection-helpers.d.ts +101 -0
  6. package/dist/collection-helpers.d.ts.map +1 -0
  7. package/dist/collection-helpers.js +206 -0
  8. package/dist/collection-helpers.js.map +1 -0
  9. package/dist/collection-resolve.d.ts +5 -0
  10. package/dist/collection-resolve.d.ts.map +1 -0
  11. package/dist/collection-resolve.js +209 -0
  12. package/dist/collection-resolve.js.map +1 -0
  13. package/dist/config.d.ts +46 -4
  14. package/dist/config.d.ts.map +1 -1
  15. package/dist/config.js +208 -88
  16. package/dist/config.js.map +1 -1
  17. package/dist/deferred-body.d.ts +19 -0
  18. package/dist/deferred-body.d.ts.map +1 -0
  19. package/dist/deferred-body.js +70 -0
  20. package/dist/deferred-body.js.map +1 -0
  21. package/dist/drawer-pipeline.d.ts +33 -0
  22. package/dist/drawer-pipeline.d.ts.map +1 -0
  23. package/dist/drawer-pipeline.js +206 -0
  24. package/dist/drawer-pipeline.js.map +1 -0
  25. package/dist/expand-pipeline.d.ts +51 -0
  26. package/dist/expand-pipeline.d.ts.map +1 -0
  27. package/dist/expand-pipeline.js +314 -0
  28. package/dist/expand-pipeline.js.map +1 -0
  29. package/dist/field-match.d.ts +43 -0
  30. package/dist/field-match.d.ts.map +1 -0
  31. package/dist/field-match.js +121 -0
  32. package/dist/field-match.js.map +1 -0
  33. package/dist/functions.d.ts +36 -0
  34. package/dist/functions.d.ts.map +1 -0
  35. package/dist/functions.js +74 -0
  36. package/dist/functions.js.map +1 -0
  37. package/dist/index.d.ts +34 -4
  38. package/dist/index.d.ts.map +1 -1
  39. package/dist/index.js +95 -4
  40. package/dist/index.js.map +1 -1
  41. package/dist/lang-map.d.ts +32 -0
  42. package/dist/lang-map.d.ts.map +1 -0
  43. package/dist/lang-map.js +76 -0
  44. package/dist/lang-map.js.map +1 -0
  45. package/dist/lib/index.d.ts +6 -0
  46. package/dist/lib/index.d.ts.map +1 -1
  47. package/dist/lib/index.js +9 -0
  48. package/dist/lib/index.js.map +1 -1
  49. package/dist/lib/read-file.d.ts +78 -0
  50. package/dist/lib/read-file.d.ts.map +1 -0
  51. package/dist/lib/read-file.js +166 -0
  52. package/dist/lib/read-file.js.map +1 -0
  53. package/dist/nodes.d.ts.map +1 -1
  54. package/dist/nodes.js +18 -2
  55. package/dist/nodes.js.map +1 -1
  56. package/dist/outline-scope.d.ts +46 -0
  57. package/dist/outline-scope.d.ts.map +1 -0
  58. package/dist/outline-scope.js +208 -0
  59. package/dist/outline-scope.js.map +1 -0
  60. package/dist/plugins.d.ts +13 -0
  61. package/dist/plugins.d.ts.map +1 -1
  62. package/dist/plugins.js +65 -1
  63. package/dist/plugins.js.map +1 -1
  64. package/dist/relationships-resolve.d.ts +4 -0
  65. package/dist/relationships-resolve.d.ts.map +1 -0
  66. package/dist/relationships-resolve.js +180 -0
  67. package/dist/relationships-resolve.js.map +1 -0
  68. package/dist/snippet-pipeline.d.ts +42 -0
  69. package/dist/snippet-pipeline.d.ts.map +1 -0
  70. package/dist/snippet-pipeline.js +219 -0
  71. package/dist/snippet-pipeline.js.map +1 -0
  72. package/dist/tags/aggregate.d.ts +19 -0
  73. package/dist/tags/aggregate.d.ts.map +1 -0
  74. package/dist/tags/aggregate.js +59 -0
  75. package/dist/tags/aggregate.js.map +1 -0
  76. package/dist/tags/card.d.ts +25 -0
  77. package/dist/tags/card.d.ts.map +1 -0
  78. package/dist/tags/card.js +138 -0
  79. package/dist/tags/card.js.map +1 -0
  80. package/dist/tags/collection.d.ts +10 -0
  81. package/dist/tags/collection.d.ts.map +1 -0
  82. package/dist/tags/collection.js +54 -0
  83. package/dist/tags/collection.js.map +1 -0
  84. package/dist/tags/conversation.d.ts.map +1 -1
  85. package/dist/tags/conversation.js +26 -6
  86. package/dist/tags/conversation.js.map +1 -1
  87. package/dist/tags/drawer.d.ts +26 -0
  88. package/dist/tags/drawer.d.ts.map +1 -0
  89. package/dist/tags/drawer.js +134 -0
  90. package/dist/tags/drawer.js.map +1 -0
  91. package/dist/tags/expand.d.ts +22 -0
  92. package/dist/tags/expand.d.ts.map +1 -0
  93. package/dist/tags/expand.js +76 -0
  94. package/dist/tags/expand.js.map +1 -0
  95. package/dist/tags/progress.d.ts +9 -0
  96. package/dist/tags/progress.d.ts.map +1 -0
  97. package/dist/tags/progress.js +96 -0
  98. package/dist/tags/progress.js.map +1 -0
  99. package/dist/tags/relationships.d.ts +12 -0
  100. package/dist/tags/relationships.d.ts.map +1 -0
  101. package/dist/tags/relationships.js +62 -0
  102. package/dist/tags/relationships.js.map +1 -0
  103. package/dist/tags/snippet.d.ts +19 -0
  104. package/dist/tags/snippet.d.ts.map +1 -0
  105. package/dist/tags/snippet.js +49 -0
  106. package/dist/tags/snippet.js.map +1 -0
  107. package/dist/util.d.ts +11 -0
  108. package/dist/util.d.ts.map +1 -1
  109. package/dist/util.js +35 -0
  110. package/dist/util.js.map +1 -1
  111. package/dist/xref-patterns.d.ts +57 -0
  112. package/dist/xref-patterns.d.ts.map +1 -0
  113. package/dist/xref-patterns.js +140 -0
  114. package/dist/xref-patterns.js.map +1 -0
  115. package/dist/xref-resolve.d.ts +22 -5
  116. package/dist/xref-resolve.d.ts.map +1 -1
  117. package/dist/xref-resolve.js +203 -79
  118. package/dist/xref-resolve.js.map +1 -1
  119. package/package.json +3 -3
package/dist/config.js CHANGED
@@ -6,6 +6,13 @@ import { BREADCRUMB_AUTO_SENTINEL } from './tags/breadcrumb.js';
6
6
  import { NAV_AUTO_SENTINEL, NAV_COLLAPSED_AUTO } from './tags/nav.js';
7
7
  import { PAGINATION_AUTO_SENTINEL } from './tags/pagination.js';
8
8
  import { resolveXrefs } from './xref-resolve.js';
9
+ import { preprocessSnippets, wrapStandaloneSnippets } from './snippet-pipeline.js';
10
+ import { registerDrawers, resolveAutoDrawerTitleLevels } from './drawer-pipeline.js';
11
+ import { applyOutlineScopeWalkers, harvestHeadingsFromRenderable } from './outline-scope.js';
12
+ import { resolveExpands } from './expand-pipeline.js';
13
+ import { resolveCollections } from './collection-resolve.js';
14
+ import { resolveRelationships } from './relationships-resolve.js';
15
+ import { resolveAggregates } from './aggregate-resolve.js';
9
16
  // ─── Budget postTransform helpers ───
10
17
  const BUDGET_CURRENCY_SYMBOLS = {
11
18
  USD: '$', EUR: '€', GBP: '£', JPY: '¥', CNY: '¥',
@@ -134,6 +141,48 @@ export const coreConfig = {
134
141
  },
135
142
  PageSection: { block: 'page-section' },
136
143
  TableOfContents: { block: 'toc' },
144
+ /* Snippet doesn't have a normal schema transform — its preprocess
145
+ * hook replaces the tag with a `fence` node, and the standalone
146
+ * wrap step adds `<figure class="rf-snippet">` post-transform.
147
+ * The engine never sees a `Snippet` tag, but we still need an
148
+ * entry in the theme config so `computeUsedCssBlocks` includes
149
+ * `snippet.css` in CSS tree-shaking when the figure is rendered. */
150
+ Snippet: { block: 'snippet' },
151
+ /* Expand emits a placeholder during transform; the postProcess hook
152
+ * substitutes the entity content wrapped in `<section
153
+ * class="rf-expand" data-rune="expand">`. Engine config provides the
154
+ * block name for CSS tree-shaking. */
155
+ Expand: { block: 'expand' },
156
+ /* Badge emits a complete `<span class="rf-badge" data-rune="badge">`
157
+ * directly from its schema and needs no engine post-processing, but
158
+ * still needs an entry in the theme config so `computeUsedCssBlocks`
159
+ * includes `badge.css` in CSS tree-shaking when a badge is rendered. */
160
+ Badge: { block: 'badge' },
161
+ /* Collection emits a sentinel during transform; the postProcess hook
162
+ * (`resolveCollections`) fills it with queried entities. Engine config
163
+ * provides the block name for CSS tree-shaking. */
164
+ Collection: { block: 'collection' },
165
+ Relationships: { block: 'relationships' },
166
+ /* Aggregate emits a sentinel during transform; the postProcess hook
167
+ * (`resolveAggregates`) fills it with either a single integer (no-body
168
+ * form) or a body-zoned breakdown. Engine config provides the block
169
+ * name for CSS tree-shaking. */
170
+ Aggregate: { block: 'aggregate' },
171
+ Progress: {
172
+ block: 'progress',
173
+ modifiers: { sentiment: { source: 'meta' } },
174
+ },
175
+ /* card — generic content card. The `layout` meta drives the shared
176
+ * split layout (split.css, data-attribute-keyed); data-media-position
177
+ * hoists the media to a full-bleed header on mobile. Named parts
178
+ * (media/content/body/footer/link) get rf-card__* from data-name. */
179
+ Card: {
180
+ block: 'card',
181
+ rootAttributes: { 'data-media-position': 'top' },
182
+ modifiers: {
183
+ layout: { source: 'meta', default: 'stacked' },
184
+ },
185
+ },
137
186
  Embed: {
138
187
  block: 'embed',
139
188
  defaultDensity: 'compact',
@@ -307,6 +356,17 @@ export const coreConfig = {
307
356
  },
308
357
  },
309
358
  },
359
+ Drawer: {
360
+ block: 'drawer',
361
+ defaultDensity: 'compact',
362
+ modifiers: {
363
+ side: { source: 'meta', default: 'right' },
364
+ size: { source: 'meta', default: 'md' },
365
+ shortcut: { source: 'meta', noBemClass: true },
366
+ },
367
+ sections: { header: 'header', body: 'body' },
368
+ editHints: { title: 'inline', body: 'none', close: 'none' },
369
+ },
310
370
  Figure: {
311
371
  block: 'figure',
312
372
  defaultDensity: 'compact',
@@ -2006,101 +2066,161 @@ navSearchScope) {
2006
2066
  // item href set is final.
2007
2067
  result = applyNavActiveState(result, pageUrl);
2008
2068
  result = resolveBlogPosts(result, coreData.allPosts, ctx, pageUrl);
2009
- result = resolveXrefs(result, pageUrl, coreData.registry, ctx);
2069
+ result = resolveXrefs(result, pageUrl, coreData.registry, coreData.xrefPatterns ?? [], ctx);
2010
2070
  return result;
2011
2071
  }
2012
2072
  /**
2013
- * Core cross-page pipeline hooks.
2014
- * Run for every site, before any plugin hooks.
2015
- * Registers page and heading entities, aggregates the page tree and breadcrumb paths,
2016
- * and resolves blog post listings.
2073
+ * Build core cross-page pipeline hooks parameterized by build-time options.
2074
+ *
2075
+ * Most callers (existing adapters, tests) use the {@link corePipelineHooks}
2076
+ * default below equivalent to `createCorePipelineHooks()` with no patterns
2077
+ * configured. The content-loader bootstrap passes compiled
2078
+ * {@link CompiledXrefPattern}s when `refrakt.config.json#/xrefs` is set.
2017
2079
  */
2018
- export const corePipelineHooks = {
2019
- register(pages, registry, ctx) {
2020
- for (const page of pages) {
2021
- const parentUrl = deriveParentUrl(page.url);
2022
- const existingPage = registry.getById('page', page.url);
2023
- if (existingPage && existingPage.sourceUrl !== page.url) {
2024
- ctx.warn(`Page '${page.url}' already registered from '${existingPage.sourceUrl}'`, page.url);
2025
- }
2026
- registry.register({
2027
- type: 'page',
2028
- id: page.url,
2029
- sourceUrl: page.url,
2030
- data: {
2031
- title: page.title,
2032
- url: page.url,
2033
- parentUrl,
2034
- draft: page.frontmatter.draft ?? false,
2035
- description: page.frontmatter.description,
2036
- date: page.frontmatter.date,
2037
- order: page.frontmatter.order,
2038
- icon: page.frontmatter.icon,
2039
- },
2040
- });
2041
- for (const h of page.headings) {
2042
- const headingId = `${page.url}#${h.id}`;
2043
- const existingHeading = registry.getById('heading', headingId);
2044
- if (existingHeading && existingHeading.sourceUrl !== page.url) {
2045
- ctx.warn(`Heading '${headingId}' already registered from '${existingHeading.sourceUrl}'`, page.url);
2080
+ export function createCorePipelineHooks(opts = {}) {
2081
+ const xrefPatterns = opts.xrefPatterns ?? [];
2082
+ const embedConfig = opts.embedConfig;
2083
+ return {
2084
+ preprocess: preprocessSnippets,
2085
+ register(pages, registry, ctx) {
2086
+ for (const page of pages) {
2087
+ const parentUrl = deriveParentUrl(page.url);
2088
+ const existingPage = registry.getById('page', page.url);
2089
+ if (existingPage && existingPage.sourceUrl !== page.url) {
2090
+ ctx.warn(`Page '${page.url}' already registered from '${existingPage.sourceUrl}'`, page.url);
2046
2091
  }
2047
2092
  registry.register({
2048
- type: 'heading',
2049
- id: headingId,
2093
+ type: 'page',
2094
+ id: page.url,
2050
2095
  sourceUrl: page.url,
2051
- data: { level: h.level, text: h.text, headingId: h.id, url: page.url },
2096
+ data: {
2097
+ title: page.title,
2098
+ url: page.url,
2099
+ parentUrl,
2100
+ draft: page.frontmatter.draft ?? false,
2101
+ description: page.frontmatter.description,
2102
+ date: page.frontmatter.date,
2103
+ order: page.frontmatter.order,
2104
+ icon: page.frontmatter.icon,
2105
+ },
2052
2106
  });
2107
+ for (const h of page.headings) {
2108
+ const headingId = `${page.url}#${h.id}`;
2109
+ const existingHeading = registry.getById('heading', headingId);
2110
+ if (existingHeading && existingHeading.sourceUrl !== page.url) {
2111
+ ctx.warn(`Heading '${headingId}' already registered from '${existingHeading.sourceUrl}'`, page.url);
2112
+ }
2113
+ registry.register({
2114
+ type: 'heading',
2115
+ id: headingId,
2116
+ sourceUrl: page.url,
2117
+ data: { level: h.level, text: h.text, headingId: h.id, url: page.url },
2118
+ });
2119
+ }
2053
2120
  }
2054
- }
2055
- },
2056
- aggregate(registry, ctx) {
2057
- const pageEntities = registry.getAll('page');
2058
- const pages = pageEntities.map(e => ({
2059
- url: e.data.url,
2060
- title: e.data.title,
2061
- parentUrl: e.data.parentUrl,
2062
- description: e.data.description,
2063
- icon: e.data.icon,
2064
- order: e.data.order,
2065
- }));
2066
- const pageTree = buildPageTree(pages);
2067
- const breadcrumbPaths = buildBreadcrumbPaths(pages);
2068
- // Quick lookup: url → { url, title } for postProcess use
2069
- const pagesByUrl = new Map(pages.map(p => [p.url, p]));
2070
- // Build heading index: "url#id"heading data
2071
- const headingIndex = new Map();
2072
- for (const h of registry.getAll('heading')) {
2073
- headingIndex.set(h.id, h.data);
2074
- }
2075
- // Blog: collect all pages as potential blog posts
2076
- const allPosts = pageEntities.map(e => ({
2077
- title: e.data.title || '',
2078
- url: e.data.url || e.id,
2079
- date: e.data.date || '',
2080
- description: e.data.description || '',
2081
- draft: e.data.draft || false,
2082
- frontmatter: e.data,
2083
- }));
2084
- return { pageTree, breadcrumbPaths, pagesByUrl, headingIndex, allPosts, registry };
2085
- },
2086
- postProcess(page, aggregated, ctx) {
2087
- const coreData = aggregated['__core__'];
2088
- if (!coreData)
2089
- return page;
2090
- let renderable = resolveAutoBreadcrumbs(page.renderable, page.url, coreData.breadcrumbPaths, coreData.pagesByUrl, ctx);
2091
- renderable = resolveAutoNavs(renderable, page.url, coreData.pagesByUrl, ctx);
2092
- // SPEC-055 build-time slug resolution (see note in resolveCoreSentinels).
2093
- renderable = resolveNavSlugs(renderable, coreData.pagesByUrl, ctx, page.url);
2094
- renderable = resolveCollapsibleNavs(renderable, page.url, coreData.pagesByUrl);
2095
- renderable = resolveCardsNavs(renderable, page.url, coreData.pagesByUrl);
2096
- renderable = resolveAutoPagination(renderable, page.url, coreData.pagesByUrl, renderable);
2097
- // SPEC-055 build-time active state.
2098
- renderable = applyNavActiveState(renderable, page.url);
2099
- renderable = resolveBlogPosts(renderable, coreData.allPosts, ctx, page.url);
2100
- renderable = resolveXrefs(renderable, page.url, coreData.registry, ctx);
2101
- if (renderable === page.renderable)
2102
- return page;
2103
- return { ...page, renderable };
2104
- },
2105
- };
2121
+ // SPEC-060 — register every drawer rune as a page-scoped entity so
2122
+ // `{% ref "drawer-id" /%}` resolves to the drawer's address.
2123
+ registerDrawers(pages, registry, ctx);
2124
+ },
2125
+ aggregate(registry, ctx) {
2126
+ const pageEntities = registry.getAll('page');
2127
+ const pages = pageEntities.map(e => ({
2128
+ url: e.data.url,
2129
+ title: e.data.title,
2130
+ parentUrl: e.data.parentUrl,
2131
+ description: e.data.description,
2132
+ icon: e.data.icon,
2133
+ order: e.data.order,
2134
+ }));
2135
+ const pageTree = buildPageTree(pages);
2136
+ const breadcrumbPaths = buildBreadcrumbPaths(pages);
2137
+ // Quick lookup: url → { url, title } for postProcess use
2138
+ const pagesByUrl = new Map(pages.map(p => [p.url, p]));
2139
+ // Build heading index: "url#id" → heading data
2140
+ const headingIndex = new Map();
2141
+ for (const h of registry.getAll('heading')) {
2142
+ headingIndex.set(h.id, h.data);
2143
+ }
2144
+ // Blog: collect all pages as potential blog posts
2145
+ const allPosts = pageEntities.map(e => ({
2146
+ title: e.data.title || '',
2147
+ url: e.data.url || e.id,
2148
+ date: e.data.date || '',
2149
+ description: e.data.description || '',
2150
+ draft: e.data.draft || false,
2151
+ frontmatter: e.data,
2152
+ }));
2153
+ return { pageTree, breadcrumbPaths, pagesByUrl, headingIndex, allPosts, registry, xrefPatterns, embedConfig };
2154
+ },
2155
+ postProcess(page, aggregated, ctx) {
2156
+ const coreData = aggregated['__core__'];
2157
+ if (!coreData)
2158
+ return page;
2159
+ let renderable = resolveAutoBreadcrumbs(page.renderable, page.url, coreData.breadcrumbPaths, coreData.pagesByUrl, ctx);
2160
+ renderable = resolveAutoNavs(renderable, page.url, coreData.pagesByUrl, ctx);
2161
+ // SPEC-055 build-time slug resolution (see note in resolveCoreSentinels).
2162
+ renderable = resolveNavSlugs(renderable, coreData.pagesByUrl, ctx, page.url);
2163
+ renderable = resolveCollapsibleNavs(renderable, page.url, coreData.pagesByUrl);
2164
+ renderable = resolveCardsNavs(renderable, page.url, coreData.pagesByUrl);
2165
+ renderable = resolveAutoPagination(renderable, page.url, coreData.pagesByUrl, renderable);
2166
+ // SPEC-055 build-time active state.
2167
+ renderable = applyNavActiveState(renderable, page.url);
2168
+ renderable = resolveBlogPosts(renderable, coreData.allPosts, ctx, page.url);
2169
+ // SPEC-060 — rewrite `data-drawer-title-auto` placeholders to the
2170
+ // appropriate `h{n}` based on outline depth. Runs before xref
2171
+ // resolution so the rewritten title doesn't carry the sentinel
2172
+ // attribute into the rendered HTML.
2173
+ renderable = resolveAutoDrawerTitleLevels(renderable);
2174
+ // SPEC-066 expand resolution — substitutes embedded entity content
2175
+ // before xref runs so refs inside substituted content are resolved
2176
+ // by the same pass as host-page refs.
2177
+ renderable = resolveExpands(renderable, page.url, coreData.registry, coreData.xrefPatterns ?? [], coreData.embedConfig, ctx);
2178
+ // SPEC-070 collection resolution — runs after expand and before xref so
2179
+ // item-template `{% ref %}`s are resolved by the same xref pass.
2180
+ renderable = resolveCollections(renderable, page.url, coreData.registry, coreData.embedConfig, ctx);
2181
+ // SPEC-072 relationships resolution — same placement rationale as
2182
+ // collection: after expand, before xref (so item-template `{% ref %}`s
2183
+ // resolve in the same xref pass).
2184
+ renderable = resolveRelationships(renderable, page.url, coreData.registry, coreData.embedConfig, ctx);
2185
+ // SPEC-076 aggregate resolution — same placement as collection /
2186
+ // relationships: after expand, before xref (so any `{% ref %}` inside
2187
+ // the body template resolves in the same xref pass).
2188
+ renderable = resolveAggregates(renderable, page.url, coreData.registry, coreData.embedConfig, ctx);
2189
+ renderable = resolveXrefs(renderable, page.url, coreData.registry, coreData.xrefPatterns ?? [], ctx);
2190
+ // SPEC-062 standalone snippet wrap: turn `<pre data-snippet-source>`
2191
+ // into `<figure class="rf-snippet">` when not inside a fence-consuming
2192
+ // container (codegroup, diff). The wrap is a no-op when the page
2193
+ // has no snippet-derived fences.
2194
+ const wrappedPage = wrapStandaloneSnippets(renderable === page.renderable ? page : { ...page, renderable }, aggregated, ctx);
2195
+ // SPEC-066 outline-scope walkers: prefix heading IDs and drop TOC
2196
+ // items inside any `data-outline-scope` subtree. Generic — any rune
2197
+ // can set the attribute and get the behaviour. Runs last so it can
2198
+ // see the final tree (including expand-substituted content once
2199
+ // that lands in v0.15.0).
2200
+ applyOutlineScopeWalkers(wrappedPage.renderable);
2201
+ // Refresh `page.headings` from the final renderable. Parse-time
2202
+ // `extractHeadings` only saw the raw AST — anything inlined by
2203
+ // postProcess (expand `level=N`, collection bodies) wouldn't make
2204
+ // it into the parse-time list, leaving the page TOC blind to those
2205
+ // headings. Skips `data-outline-scope` subtrees so peer-document
2206
+ // embeds stay isolated, matching the TOC walker.
2207
+ const harvested = harvestHeadingsFromRenderable(wrappedPage.renderable);
2208
+ if (harvested.length > 0 || wrappedPage.headings.length > 0) {
2209
+ return { ...wrappedPage, headings: harvested };
2210
+ }
2211
+ return wrappedPage;
2212
+ },
2213
+ };
2214
+ }
2215
+ /**
2216
+ * Core cross-page pipeline hooks (no xref patterns configured).
2217
+ *
2218
+ * Equivalent to `createCorePipelineHooks()`. The content loader bootstrap
2219
+ * uses {@link createCorePipelineHooks} directly when
2220
+ * `refrakt.config.json#/xrefs` is configured so the resolver can use the
2221
+ * compiled patterns as a URL-resolution fallback. Run for every site,
2222
+ * before any plugin hooks. Registers page and heading entities, aggregates
2223
+ * the page tree and breadcrumb paths, and resolves blog post listings.
2224
+ */
2225
+ export const corePipelineHooks = createCorePipelineHooks();
2106
2226
  //# sourceMappingURL=config.js.map