uniweb 0.26.4 → 0.27.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "uniweb",
3
- "version": "0.26.4",
3
+ "version": "0.27.1",
4
4
  "description": "Create structured Vite + React sites with content/code separation",
5
5
  "type": "module",
6
6
  "bin": {
@@ -41,15 +41,15 @@
41
41
  "js-yaml": "^4.1.0",
42
42
  "prompts": "^2.4.2",
43
43
  "tar": "^7.0.0",
44
- "@uniweb/runtime": "^0.12.5",
45
- "@uniweb/kit": "^0.13.0",
46
- "@uniweb/semantic-parser": "^1.2.3",
47
- "@uniweb/core": "^0.10.2"
44
+ "@uniweb/runtime": "^0.12.7",
45
+ "@uniweb/semantic-parser": "^1.3.0",
46
+ "@uniweb/core": "^0.11.1",
47
+ "@uniweb/kit": "^0.13.2"
48
48
  },
49
49
  "peerDependencies": {
50
- "@uniweb/build": "^0.24.5",
51
- "@uniweb/semantic-parser": "^1.2.3",
52
- "@uniweb/content-reader": "^1.2.3"
50
+ "@uniweb/content-reader": "^1.2.4",
51
+ "@uniweb/semantic-parser": "^1.3.0",
52
+ "@uniweb/build": "^0.25.0"
53
53
  },
54
54
  "peerDependenciesMeta": {
55
55
  "@uniweb/build": {
@@ -305,11 +305,11 @@ type: Hero
305
305
  theme: dark
306
306
  ---
307
307
 
308
- ### V1.0.0 IS OUT ← pretitle (small label above the title)
308
+ #> New in v1 ← pretitle (the label line above the title)
309
309
 
310
310
  # Build the system. ← title (the big headline)
311
311
 
312
- ## Not every page. ← subtitle
312
+ ## Not every page. ← subtitle (one step smaller, directly below)
313
313
 
314
314
  Description paragraph.
315
315
 
@@ -318,7 +318,7 @@ Description paragraph.
318
318
  ![Image](./image.jpg)
319
319
  ```
320
320
 
321
- Heading levels set *structure* (pretitle, title, subtitle), not font size — the component controls visual sizing.
321
+ Heading levels set *structure* (pretitle, title, subtitle), not font size — the component controls visual sizing. The `#>` label line marks a pretitle explicitly (any number of leading `#`s spells the same label); a smaller ordinary heading directly above the title also becomes the pretitle.
322
322
 
323
323
  **A section with no `type:` renders through the foundation's default section type — a component named `Section`, unless the foundation's `main.js` sets `defaultSection` to something else.** This is what lets a folder of plain markdown with no frontmatter at all become pages: mounted documentation, an imported wiki, anything written before it met this framework. If such content renders blank, the foundation has no `Section` — that, not the markdown, is what to fix.
324
324
 
@@ -333,8 +333,10 @@ The semantic parser produces a flat, guaranteed structure. No null checks needed
333
333
  ```js
334
334
  content = {
335
335
  title: '', // Main heading (string or string[] for multi-line)
336
- pretitle: '', // Heading before main title (auto-detected)
337
- subtitle: '', // Heading after title (string or string[] for multi-line)
336
+ pretitle: '', // `#>` label line(s), or smaller headings stacked above
337
+ // the title (string or string[])
338
+ subtitle: '', // Line(s) one step below the title — each further
339
+ // one-step descent is another line (string or string[])
338
340
  paragraphs: [], // Text blocks
339
341
  links: [], // { href, label, role } — standalone links (not inside lists)
340
342
  images: [], // { src, alt, role, href }
@@ -347,7 +349,8 @@ content = {
347
349
  data: {}, // Tagged blocks — ```yaml:tag / ```json:tag give the parsed value,
348
350
  // ```md:tag gives { items, sequence } (see Concept blocks)
349
351
  tables: [], // Only when present — [{ rows: [{ cells: [{ children, header, align }] }] }]
350
- headings: [], // Headings after subtitle, in document order
352
+ headings: [], // Only from nested content (quote/list bodies) — a
353
+ // section's headline never spills here
351
354
  items: [], // Each has the same flat structure — from headings after body content
352
355
  sequence: [], // All elements in document order
353
356
  }
@@ -358,7 +361,7 @@ content = {
358
361
  ### Markdown → content, side by side
359
362
 
360
363
  ```markdown
361
- ### Eyebrow │ content.pretitle = "Eyebrow"
364
+ #> Eyebrow │ content.pretitle = "Eyebrow"
362
365
  # Our Features │ content.title = "Our Features"
363
366
  ## Build better products │ content.subtitle = "Build better products"
364
367
 
@@ -375,7 +378,7 @@ Lightning quick. │ content.items[0].paragraphs[0] = "Lightning
375
378
  Enterprise-grade security. │ content.items[1].paragraphs[0] = "Enterprise-grade…"
376
379
  ```
377
380
 
378
- The three rules that produce this: headings *before* the main title become `pretitle`; a heading *after* the title at lower importance becomes `subtitle`; headings appearing *after body content* start the `items` array.
381
+ The staircase rule produces this each heading relates to the one before it: the same size adds another line to the same part; **one step smaller** joins the headline as the next part down (the subtitle, then further subtitle lines); **two steps smaller** starts an item; and once body content has begun, *any* heading starts an item. `#>` label lines, and smaller headings stacked above the title, become `pretitle`.
379
382
 
380
383
  ### Items have the full content shape
381
384
 
@@ -391,21 +394,20 @@ seats: 1
391
394
  ``` ← items[0].data.details = { trial: "14 days", seats: 1 }
392
395
  ````
393
396
 
394
- ### Subtitle vs items — the level rule
397
+ ### Subtitle vs items — the step rule
395
398
 
396
- A heading immediately after the title becomes `subtitle` **only when it is exactly one level deeper** (H1→H2, H2→H3). Skipping levels (H1→H3) breaks the group and the deeper heading starts items instead. To get items with no subtitle, close the title group with a `---` divider or a paragraph:
399
+ A heading directly after the title becomes `subtitle` **only when it is exactly one step smaller** (H1→H2, H2→H3) and each *further* one-step line continues the subtitle (a three-line header is `subtitle: [line2, line3]`). **Two steps smaller starts items** the idiom for entries with no lead paragraph:
397
400
 
398
401
  ```markdown
399
402
  # Our Stats │ content.title = "Our Stats"
400
- --- divider closes the title group
401
- ## 15,000+ │ content.items[0].title = "15,000+"
403
+ ### 15,000+ content.items[0].title = "15,000+"
402
404
  Students from 90 countries │ content.items[0].paragraphs[0]
403
405
 
404
- ## 200+ │ content.items[1].title = "200+"
406
+ ### 200+ │ content.items[1].title = "200+"
405
407
  Programs offered │ content.items[1].paragraphs[0]
406
408
  ```
407
409
 
408
- Without the `---`, `## 15,000+` would become `content.subtitle`.
410
+ With `## 15,000+` instead, the first stat would join the headline as `content.subtitle`. A `---` divider, or any body content after the headline, also closes it — after body, headings of *any* size start items.
409
411
 
410
412
  ### Multi-line headings
411
413
 
@@ -421,7 +423,7 @@ Consecutive headings at the same level merge into a title array — one heading
421
423
  │ ]
422
424
  ```
423
425
 
424
- **Rule:** same-level continuation only applies *before* going deeper. Once a subtitle level is reached, same-level headings start new items instead of merging. Use `---` to force separate items where headings would otherwise merge.
426
+ **Rule:** a repeated size always continues the part it repeats title lines, or subtitle lines once the headline has stepped down. Use `---` to force separate items where adjacent headings would otherwise continue the headline.
425
427
 
426
428
  ### Sequential content
427
429
 
@@ -2047,6 +2049,11 @@ yes, so an event added in a later framework release is included without you
2047
2049
  changing anything — which is exactly why `standard` exists as well: it is a
2048
2050
  curated set that a release cannot grow behind your back.
2049
2051
 
2052
+ A site can also set **`flushIntervalMs`** to widen the batching window (default
2053
+ 5000, milliseconds — `30` is thirty *milliseconds*). A host that supplies your
2054
+ collector may set it for you and your own value wins; the trade is fewer
2055
+ requests against more tail loss at the end of a visit.
2056
+
2050
2057
  ⚠️ **`emit` never limits what YOU send.** `block.track()` and `useTracker()` are
2051
2058
  not filtered by it — the registry is open, and your events are yours. It governs
2052
2059
  only the ones the framework emits on its own. A host may narrow the list further
@@ -2414,7 +2421,7 @@ Most Uniweb failures are **silent** — the build succeeds and the page is wrong
2414
2421
 
2415
2422
  **A section doesn't appear at all** — the file is `@`-prefixed (a child section, only rendered via `nest:`), or `_`-prefixed (treated as a draft and skipped), or it's a section type nested below the root of `sections/` without a `meta.js`, which means it was never discovered.
2416
2423
 
2417
- **Content lands in the wrong field** — a heading became a `subtitle` when you wanted an item, or the reverse. That's the level rule (exactly one level deeper = subtitle; skipping a level, or any body content first, starts items). Run `uniweb inspect <path>` rather than re-deriving it.
2424
+ **Content lands in the wrong field** — a heading became a `subtitle` when you wanted an item, or the reverse. That's the step rule (one step smaller and adjacent = the next headline line; two steps, a divider, or any body content first = items). Run `uniweb inspect <path>` rather than re-deriving it.
2418
2425
 
2419
2426
  **A var in frontmatter does nothing** — component vars only apply when declared in that section type's `meta.js` `vars:`. Unknown names are ignored silently.
2420
2427
 
@@ -56,7 +56,10 @@ async function loadDependencies() {
56
56
  ])
57
57
  return {
58
58
  markdownToProseMirror: contentReader.markdownToProseMirror,
59
- parseContent: semanticParser.parseContent
59
+ parseContent: semanticParser.parseContent,
60
+ // Optional: present from @uniweb/semantic-parser >= the staircase
61
+ // release; older installs simply show no findings.
62
+ lintContent: semanticParser.lintContent
60
63
  }
61
64
  } catch {
62
65
  console.error(
@@ -303,6 +306,13 @@ function processFile(fileContent, fileName, deps, options) {
303
306
 
304
307
  if (insets.length > 0) result.insets = insets
305
308
 
309
+ // Grouping near-miss findings — shapes that usually mean the author got a
310
+ // different structure than they wanted (an entry absorbed into the
311
+ // headline, a hand-written eyebrow demoting the title). Observation only:
312
+ // the parse above is untouched.
313
+ const findings = deps.lintContent?.(doc) || []
314
+ if (findings.length > 0) result.findings = findings
315
+
306
316
  return result
307
317
  }
308
318
 
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "generatedAt": "2026-08-19T17:26:33.370Z",
3
+ "generatedAt": "2026-08-20T22:44:56.592Z",
4
4
  "packages": {
5
5
  "@uniweb/build": {
6
- "version": "0.24.5",
6
+ "version": "0.25.0",
7
7
  "path": "framework/build",
8
8
  "deps": [
9
9
  "@uniweb/content-reader",
@@ -19,17 +19,17 @@
19
19
  ]
20
20
  },
21
21
  "@uniweb/content-reader": {
22
- "version": "1.2.3",
22
+ "version": "1.2.4",
23
23
  "path": "framework/content-reader",
24
24
  "deps": []
25
25
  },
26
26
  "@uniweb/content-writer": {
27
- "version": "0.3.3",
27
+ "version": "0.3.4",
28
28
  "path": "framework/content-writer",
29
29
  "deps": []
30
30
  },
31
31
  "@uniweb/core": {
32
- "version": "0.10.2",
32
+ "version": "0.11.1",
33
33
  "path": "framework/core",
34
34
  "deps": [
35
35
  "@uniweb/semantic-parser",
@@ -42,14 +42,14 @@
42
42
  "deps": []
43
43
  },
44
44
  "@uniweb/icons": {
45
- "version": "0.4.1",
45
+ "version": "0.4.2",
46
46
  "path": "framework/icons",
47
47
  "deps": [
48
48
  "@uniweb/core"
49
49
  ]
50
50
  },
51
51
  "@uniweb/kit": {
52
- "version": "0.13.0",
52
+ "version": "0.13.2",
53
53
  "path": "framework/kit",
54
54
  "deps": [
55
55
  "@uniweb/core",
@@ -68,7 +68,7 @@
68
68
  "deps": []
69
69
  },
70
70
  "@uniweb/projections": {
71
- "version": "0.3.3",
71
+ "version": "0.3.4",
72
72
  "path": "framework/projections",
73
73
  "deps": [
74
74
  "@uniweb/content-writer",
@@ -76,7 +76,7 @@
76
76
  ]
77
77
  },
78
78
  "@uniweb/runtime": {
79
- "version": "0.12.5",
79
+ "version": "0.12.7",
80
80
  "path": "framework/runtime",
81
81
  "deps": [
82
82
  "@uniweb/core",
@@ -99,7 +99,7 @@
99
99
  "deps": []
100
100
  },
101
101
  "@uniweb/semantic-parser": {
102
- "version": "1.2.3",
102
+ "version": "1.3.0",
103
103
  "path": "framework/semantic-parser",
104
104
  "deps": []
105
105
  },
@@ -114,7 +114,7 @@
114
114
  "deps": []
115
115
  },
116
116
  "@uniweb/unipress": {
117
- "version": "0.8.10",
117
+ "version": "0.8.11",
118
118
  "path": "framework/unipress",
119
119
  "deps": [
120
120
  "@uniweb/build",