uniweb 0.49.0 → 0.50.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "uniweb",
3
- "version": "0.49.0",
3
+ "version": "0.50.0",
4
4
  "description": "Create structured Vite + React sites with content/code separation",
5
5
  "type": "module",
6
6
  "bin": {
@@ -41,13 +41,13 @@
41
41
  "js-yaml": "^4.1.0",
42
42
  "prompts": "^2.4.2",
43
43
  "tar": "^7.0.0",
44
- "@uniweb/core": "^0.25.0",
44
+ "@uniweb/core": "^0.25.1",
45
45
  "@uniweb/kit": "^0.18.3",
46
46
  "@uniweb/semantic-parser": "^1.4.0",
47
- "@uniweb/runtime": "^0.20.0"
47
+ "@uniweb/runtime": "^0.20.1"
48
48
  },
49
49
  "peerDependencies": {
50
- "@uniweb/build": "^0.45.0",
50
+ "@uniweb/build": "^0.46.0",
51
51
  "@uniweb/content-reader": "^1.2.4",
52
52
  "@uniweb/semantic-parser": "^1.4.0"
53
53
  },
@@ -874,12 +874,12 @@ team:
874
874
 
875
875
  You can keep the same declarations under `queries:` in `site.yml` instead, if you would rather have one file.
876
876
 
877
- **Show a query on a page** with `data:` in `page.yml` (the whole result), or `fetch:` in a section's frontmatter (a subset). A list — `data: [team, articles]` — declares several, each arriving under its own `content.data` key:
877
+ **Show a query on a page** with `query:` in `page.yml` or a section's frontmatter (the whole result), or `fetch:` for anything more a `limit`, a `where`. A list — `query: [team, articles]` — declares several, each arriving under its own `content.data` key. `query:` takes names only; `data:`, its old name, is now an error.
878
878
 
879
879
  ```yaml
880
880
  # pages/blog/page.yml | # a section on the homepage
881
881
  title: Blog | ---
882
- data: recent | type: ArticleTeaser
882
+ query: recent | type: ArticleTeaser
883
883
  | fetch: { query: recent, limit: 3 }
884
884
  | ---
885
885
  ```
@@ -888,7 +888,7 @@ data: recent | type: ArticleTeaser
888
888
 
889
889
  ```
890
890
  pages/blog/
891
- ├── page.yml # title: Blog / data: recent
891
+ ├── page.yml # title: Blog / query: recent
892
892
  ├── list.md
893
893
  └── [slug]/
894
894
  ├── page.yml
@@ -897,7 +897,7 @@ pages/blog/
897
897
 
898
898
  `entities/article/design-tips.md` becomes `/blog/design-tips`. The section inside `[slug]/` needs no special markdown — the matched record is delivered to it. Generated pages are excluded from navigation menus.
899
899
 
900
- **Which query the URL narrows — the page's route query:** the `[slug]` page's own `data:`, else its parent page's (the usual shape, above), else `site.yml`'s; if none declares one, the query its sections all declare. The first query of that level wins. Every section the route query reaches gets the one record; a section declaring a *different* query of its own gets that query as declared. The folder name says what the URL segment matches: `[slug]` the record's handle (`$name`, which compiled records carry — equal to their `slug`), `[uuid]` its `$uuid`, any other `[name]` the record's own field of that name. A folder inside `[slug]/` (`[slug]/cv/` → `/blog/:slug/cv`) is a parametric page too, reading the record when `[slug]/page.yml` declares the query. `[dir]` and `[path]` are refused as folder names, and so is any folder inside `[...path]/`.
900
+ **Which query the URL narrows — the page's route query:** the `[slug]` page's own `query:`, else its parent page's (the usual shape, above), else `site.yml`'s; if none declares one, the query its sections all declare. The first query of that level wins. Every section the route query reaches gets the one record; a section declaring a *different* query of its own gets that query as declared. The folder name says what the URL segment matches: `[slug]` the record's handle (`$name`, which compiled records carry — equal to their `slug`), `[uuid]` its `$uuid`, any other `[name]` the record's own field of that name. A folder inside `[slug]/` (`[slug]/cv/` → `/blog/:slug/cv`) is a parametric page too, reading the record when `[slug]/page.yml` declares the query. `[dir]` and `[path]` are refused as folder names, and so is any folder inside `[...path]/`.
901
901
 
902
902
  > **The record arrives as a single-element array under the query key** — `content.data.recent[0]`, not `content.data.article`. The runtime never coerces it to an object and never synthesizes a singular key. See *Data* in Part 4.
903
903
 
@@ -977,7 +977,7 @@ function MyComponent({ content, params, block }) {
977
977
  }
978
978
  ```
979
979
 
980
- Frontmatter becomes `params`, minus the keys the framework consumes outright: `type`, `preset`, `input`, `props`, `fetch`, `data`, `id`. `props:` is the one that isn't dropped but merged *into* params.
980
+ Frontmatter becomes `params`, minus the keys the framework consumes outright: `type`, `preset`, `input`, `props`, `query`, `fetch`, `id` (a `data:` key is refused — it was `query:`'s old name). `props:` is the one that isn't dropped but merged *into* params.
981
981
 
982
982
  **Framework fields you'd expect to be stripped are not.** `background`, `theme`, `source`, `where`, and `vars` are acted on by the runtime *and* passed through — so `params.theme` is readable when a component needs logic beyond CSS tokens (a light vs. dark logo, say). Components ignore the keys they don't use, the same way they ignore unused `content.data` keys.
983
983
 
@@ -1608,7 +1608,7 @@ export default function Grid({ block, params }) {
1608
1608
 
1609
1609
  Each child is a regular section with its own type, params, and content — and you're in the middle: wrap each child, filter by type, reorder, add container classes. The author decides *what* goes in the grid; your component decides *how* it renders. Tomorrow the author can swap a child for a different section type with no code change, and your components stay reusable wherever child sections are accepted.
1610
1610
 
1611
- **Data and child blocks:** page-level `data:` is available to all blocks including children, and each child resolves data independently through the page → site hierarchy. If a child needs data, declare it in the child's `meta.js` or its frontmatter (`data: articles`).
1611
+ **Data and child blocks:** page-level `query:` (or `fetch:`) is available to all blocks including children, and each child resolves data independently through the page → site hierarchy. If a child needs data no ancestor declares, give it its own in its frontmatter (`query: articles`, or `fetch:`). Its `meta.js` `data:` declares the shape it reads, never where the data comes from — it fetches nothing.
1612
1612
 
1613
1613
  **SSG:** insets, `<ChildBlocks>`, and `<Visual>` all render correctly during prerender. Inset components using React hooks internally trigger prerender warnings — expected and harmless; the page renders correctly client-side.
1614
1614
 
@@ -1773,7 +1773,7 @@ Content-less containers appear as group nodes (`hasContent: false`) — use `nav
1773
1773
 
1774
1774
  ### Data
1775
1775
 
1776
- A component on a page with a `data:` or `fetch:` declaration automatically receives that data in `content.data.{key}` — no opt-in in `meta.js`.
1776
+ A component on a page with a `query:` or `fetch:` declaration automatically receives that data in `content.data.{key}` — no opt-in in `meta.js`.
1777
1777
 
1778
1778
  **Bound collections always arrive as arrays.** On a list page, `content.data.articles` is the full collection. On a parametric page (`[slug]/`), the matched record is delivered under the *same* key as a single-element array — the detail section reads `content.data.articles[0]`. When nothing matches, the key is `[]`. The runtime never coerces to a single object and never synthesizes a singular key.
1779
1779
 
@@ -1831,7 +1831,7 @@ A backend with its own base URL, headers, wire or query language is a **transpor
1831
1831
  # site.yml
1832
1832
  fetcher:
1833
1833
  transports:
1834
- articles: acme # a foundation-registered transport handles `data: articles`
1834
+ articles: acme # a foundation-registered transport handles `query: articles`
1835
1835
  events: default # explicitly route back to the default fetcher
1836
1836
  acme: # binding config that transport reads
1837
1837
  apiKey: pk_public_123
@@ -772,12 +772,12 @@ export async function publish(args = []) {
772
772
  // released version on the wire is required when site.yml uses an unversioned
773
773
  // local ref; injectInfo overrides info.foundation. A registry/URL ref → fnd.ref
774
774
  // is null → the site.yml ref is forwarded verbatim (already pinned).
775
- // ⛔ DO NOT STAMP `info.data` HERE. The name is TAKEN: `uwx/site.js` already
776
- // emits `info.data` from `site.yml`'s top-level `data:`/`fetch:` block, and
777
- // `injectInfo` WINS the merge (`sync-package.js`: `{...siteDoc.info,
778
- // ...injectInfo}`), so stamping a file map here silently replaces the author's
779
- // fetch config on the wire. Both are `type: json`, so the store validator
780
- // accepts either and nothing errors at any layer.
775
+ // ⛔ DO NOT STAMP A FILE MAP INTO `info` HERE. `injectInfo` WINS the merge
776
+ // (`sync-package.js`: `{...siteDoc.info, ...injectInfo}`), so any name stamped
777
+ // here silently replaces what the author's document carries under it, and the
778
+ // store validator accepts it nothing errors at any layer. This was written
779
+ // about `info.data`, which carried the site's `fetch:` block until 2026-09-09;
780
+ // that moved to `settings.fetch`, and the warning holds for any name.
781
781
  //
782
782
  // A file map needs a name nothing else claims (`static_data` / `data_files`
783
783
  // were proposed) AND a consumer that reads it — neither settled. See
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "generatedAt": "2026-09-11T18:41:11.718Z",
3
+ "generatedAt": "2026-09-11T23:04:50.071Z",
4
4
  "packages": {
5
5
  "@uniweb/api": {
6
6
  "version": "0.3.2",
@@ -10,7 +10,7 @@
10
10
  ]
11
11
  },
12
12
  "@uniweb/build": {
13
- "version": "0.45.0",
13
+ "version": "0.46.0",
14
14
  "path": "framework/build",
15
15
  "deps": [
16
16
  "@uniweb/content-reader",
@@ -34,7 +34,7 @@
34
34
  "deps": []
35
35
  },
36
36
  "@uniweb/core": {
37
- "version": "0.25.0",
37
+ "version": "0.25.1",
38
38
  "path": "framework/core",
39
39
  "deps": [
40
40
  "@uniweb/semantic-parser",
@@ -82,7 +82,7 @@
82
82
  ]
83
83
  },
84
84
  "@uniweb/runtime": {
85
- "version": "0.20.0",
85
+ "version": "0.20.1",
86
86
  "path": "framework/runtime",
87
87
  "deps": [
88
88
  "@uniweb/core",
@@ -120,7 +120,7 @@
120
120
  "deps": []
121
121
  },
122
122
  "@uniweb/unipress": {
123
- "version": "0.9.12",
123
+ "version": "0.9.13",
124
124
  "path": "framework/unipress",
125
125
  "deps": [
126
126
  "@uniweb/build",
@@ -49,8 +49,8 @@ index: home
49
49
  # sort: date desc
50
50
  # limit: 10
51
51
  #
52
- # Pages and sections then name a query: `data: recent`, or
53
- # `fetch: { query: recent }`.
52
+ # Pages and sections then name a query: `query: recent`, or
53
+ # `fetch: { query: recent, limit: 3 }` for anything more.
54
54
  #
55
55
  # You can also keep queries here instead of in queries.yml:
56
56
  #
@@ -61,7 +61,7 @@ index: home
61
61
  #
62
62
  # fetch:
63
63
  # - url: https://api.example.com/team # Remote JSON
64
- # schema: team # Access as content.data.team
64
+ # as: team # Access as content.data.team
65
65
  # - path: /data/config.json # Local file from public/
66
66
 
67
67
  # ─── Extensions ────────────────────────────────────────────────────────────────