uniweb 0.10.2 → 0.10.4

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/README.md CHANGED
@@ -257,7 +257,7 @@ You can delete the `foundation/` folder entirely and point your site at a publis
257
257
 
258
258
  _Site-first_ — You're building a website. The foundation is your component library, co-developed with the site. This is the common case.
259
259
 
260
- _Foundation-first_ — You're building a component system. The site is a test harness with sample content. The real sites live elsewhere—other repositories, other teams, or managed on [uniweb.app](https://uniweb.app). Use `uniweb add site` to add multiple test sites exercising a shared foundation.
260
+ _Foundation-first_ — You're building a component system. The site is a test harness with sample content. The real sites live elsewhere—other repositories, other teams, or managed on [hub.uniweb.app](https://hub.uniweb.app). Use `uniweb add site` to add multiple test sites exercising a shared foundation.
261
261
 
262
262
  ## Growing Your Project
263
263
 
@@ -299,11 +299,11 @@ The structure you start with scales without rewrites:
299
299
 
300
300
  1. **Single project** — One site, one foundation. Develop and deploy together. Most projects stay here.
301
301
 
302
- 2. **Published foundation** — Release your foundation as an npm package or to [uniweb.app](https://uniweb.app). Other sites can use it without copying code.
302
+ 2. **Published foundation** — Release your foundation as an npm package or to [hub.uniweb.app](https://hub.uniweb.app). Other sites can use it without copying code.
303
303
 
304
304
  3. **Multiple sites** — Several sites share one foundation. Update components once, every site benefits.
305
305
 
306
- 4. **Platform-managed sites** — Sites built on [uniweb.app](https://uniweb.app) with visual editing tools can use your foundation. You develop components locally; content teams work in the browser.
306
+ 4. **Platform-managed sites** — Sites built on [hub.uniweb.app](https://hub.uniweb.app) with visual editing tools can use your foundation. You develop components locally; content teams work in the browser.
307
307
 
308
308
  Start with local files deployed anywhere. The same foundation works across all these scenarios.
309
309
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "uniweb",
3
- "version": "0.10.2",
3
+ "version": "0.10.4",
4
4
  "description": "Create structured Vite + React sites with content/code separation",
5
5
  "type": "module",
6
6
  "bin": {
@@ -41,14 +41,14 @@
41
41
  "js-yaml": "^4.1.0",
42
42
  "prompts": "^2.4.2",
43
43
  "tar": "^7.0.0",
44
- "@uniweb/core": "0.7.1",
45
- "@uniweb/runtime": "0.8.2",
46
- "@uniweb/kit": "0.9.1"
44
+ "@uniweb/runtime": "0.8.3",
45
+ "@uniweb/kit": "0.9.2",
46
+ "@uniweb/core": "0.7.2"
47
47
  },
48
48
  "peerDependencies": {
49
- "@uniweb/build": "0.10.2",
49
+ "@uniweb/build": "0.10.3",
50
50
  "@uniweb/content-reader": "1.1.4",
51
- "@uniweb/semantic-parser": "1.1.9"
51
+ "@uniweb/semantic-parser": "1.1.10"
52
52
  },
53
53
  "peerDependenciesMeta": {
54
54
  "@uniweb/build": {
@@ -891,7 +891,7 @@ fetch:
891
891
  limit: 3
892
892
  ```
893
893
 
894
- **Lean lists with `deferred:`.** Collections with heavy fields (article bodies, large nested arrays) can declare `deferred: [body]` in `site.yml`. The cascade payload omits those fields; per-record full files are emitted at `/data/<name>/<slug>.json` (markdown-backed collections) or fetched from an author-declared `detailUrl:` pattern (API-backed collections). On dynamic-route pages the focused entity's full record is delivered automatically; elsewhere components fetch on demand via the `useEntityDetail` kit hook.
894
+ **Lean lists with `deferred:`.** Collections with heavy fields (article bodies, large nested arrays) can declare `deferred: [body]` in `site.yml`. The cascade payload omits those fields; per-record full files are emitted at `/data/<name>/<slug>.json` (file-based collections — markdown, YAML, or JSON) or fetched from an author-declared `detailUrl:` pattern (API-backed collections). On dynamic-route pages the focused entity's full record is delivered automatically; elsewhere components fetch on demand via the `useEntityDetail` kit hook.
895
895
 
896
896
  **Component-side fetching.** When a component genuinely needs to fetch something on its own (a search box, a "load more" button, a popover that lazy-loads), use the kit hooks (`useFetched`, `useCacheEntry`, `useEntityDetail`). They share the framework's cache and dispatcher with declarative fetches; same-key requests dedupe automatically.
897
897
 
@@ -11,9 +11,10 @@
11
11
  */
12
12
 
13
13
  import { existsSync, readFileSync } from 'node:fs'
14
- import { resolve, join } from 'node:path'
14
+ import { resolve, join, dirname } from 'node:path'
15
15
  import { spawn } from 'node:child_process'
16
16
  import { writeFile, mkdir } from 'node:fs/promises'
17
+ import { createRequire } from 'node:module'
17
18
 
18
19
  // Import build utilities from @uniweb/build
19
20
  import {
@@ -123,6 +124,46 @@ function runCommand(command, args, cwd) {
123
124
  })
124
125
  }
125
126
 
127
+ /**
128
+ * Resolve the project's local Vite binary.
129
+ *
130
+ * We intentionally do NOT fall back to `npx vite`: npx resolves through npm's
131
+ * global cache, which may hold a stale Vite version (e.g. Vite 5 ignores
132
+ * lib.fileName for CSS and always emits style.css). Using the project's local
133
+ * Vite guarantees the version declared in package.json is the one that runs.
134
+ *
135
+ * @param {string} projectDir
136
+ * @returns {string} Absolute path to the vite CLI entry
137
+ */
138
+ function resolveLocalVite(projectDir) {
139
+ const require = createRequire(join(projectDir, 'package.json'))
140
+ let pkgJsonPath
141
+ try {
142
+ pkgJsonPath = require.resolve('vite/package.json')
143
+ } catch {
144
+ throw new Error(
145
+ `Vite is not installed in ${projectDir}.\n` +
146
+ `Run \`pnpm install\` (or npm/yarn install) in the project before building.`
147
+ )
148
+ }
149
+ const pkg = JSON.parse(readFileSync(pkgJsonPath, 'utf8'))
150
+ const binRel = typeof pkg.bin === 'string' ? pkg.bin : pkg.bin?.vite
151
+ if (!binRel) {
152
+ throw new Error(`Could not find vite bin entry in ${pkgJsonPath}`)
153
+ }
154
+ return join(dirname(pkgJsonPath), binRel)
155
+ }
156
+
157
+ /**
158
+ * Run the project's local Vite with the given args.
159
+ * @param {string} projectDir
160
+ * @param {string[]} args - e.g. ['build']
161
+ */
162
+ async function runLocalVite(projectDir, args) {
163
+ const viteBin = resolveLocalVite(projectDir)
164
+ await runCommand(process.execPath, [viteBin, ...args], projectDir)
165
+ }
166
+
126
167
  /**
127
168
  * Build a foundation
128
169
  */
@@ -158,7 +199,7 @@ async function buildFoundation(projectDir, options = {}) {
158
199
 
159
200
  // Check if vite.config.js uses the generated entry
160
201
  // For now, just run the standard vite build
161
- await runCommand('npx', ['vite', 'build'], projectDir)
202
+ await runLocalVite(projectDir, ['build'])
162
203
 
163
204
  // Vite's foundation plugin generates dist/meta/schema.json
164
205
  // and processes preview images during the build.
@@ -351,7 +392,7 @@ async function buildSite(projectDir, options = {}) {
351
392
  info('Building site...')
352
393
 
353
394
  // Run vite build for sites
354
- await runCommand('npx', ['vite', 'build'], projectDir)
395
+ await runLocalVite(projectDir, ['build'])
355
396
 
356
397
  success('Site build complete')
357
398
 
@@ -160,7 +160,7 @@ function showWebHandoff(email, name) {
160
160
  console.log('')
161
161
  info(`Web-based handoff`)
162
162
  console.log('')
163
- console.log(` 1. Create a site on ${colors.cyan}uniweb.app${colors.reset} using ${colors.bright}${name}${colors.reset}`)
163
+ console.log(` 1. Create a site on ${colors.cyan}hub.uniweb.app${colors.reset} using ${colors.bright}${name}${colors.reset}`)
164
164
  console.log(` 2. Add pages and content`)
165
165
  console.log(` 3. Transfer ownership to ${colors.bright}${email}${colors.reset}:`)
166
166
  console.log(` ${colors.dim}Settings → Transfer site${colors.reset}`)
@@ -275,10 +275,10 @@ async function handleCreate(args, email) {
275
275
  console.log('')
276
276
  if (isExtension) {
277
277
  console.log(` ${colors.dim}When ${invite.email} adds ${name} to their site${colors.reset}`)
278
- console.log(` ${colors.dim}on uniweb.app or Studio, it will be authorized automatically.${colors.reset}`)
278
+ console.log(` ${colors.dim}on hub.uniweb.app or Studio, it will be authorized automatically.${colors.reset}`)
279
279
  } else {
280
280
  console.log(` ${colors.dim}When ${invite.email} creates a site with ${name}${colors.reset}`)
281
- console.log(` ${colors.dim}on uniweb.app or Studio, it will be authorized automatically.${colors.reset}`)
281
+ console.log(` ${colors.dim}on hub.uniweb.app or Studio, it will be authorized automatically.${colors.reset}`)
282
282
  }
283
283
  } catch (err) {
284
284
  error(err.message)
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "generatedAt": "2026-04-19T04:51:09.611Z",
3
+ "generatedAt": "2026-04-23T17:16:28.977Z",
4
4
  "packages": {
5
5
  "@uniweb/build": {
6
- "version": "0.10.2",
6
+ "version": "0.10.3",
7
7
  "path": "framework/build",
8
8
  "deps": [
9
9
  "@uniweb/content-reader",
@@ -24,7 +24,7 @@
24
24
  "deps": []
25
25
  },
26
26
  "@uniweb/core": {
27
- "version": "0.7.1",
27
+ "version": "0.7.2",
28
28
  "path": "framework/core",
29
29
  "deps": [
30
30
  "@uniweb/semantic-parser",
@@ -42,7 +42,7 @@
42
42
  "deps": []
43
43
  },
44
44
  "@uniweb/kit": {
45
- "version": "0.9.1",
45
+ "version": "0.9.2",
46
46
  "path": "framework/kit",
47
47
  "deps": [
48
48
  "@uniweb/core"
@@ -54,12 +54,12 @@
54
54
  "deps": []
55
55
  },
56
56
  "@uniweb/press": {
57
- "version": "0.2.8",
57
+ "version": "0.3.1",
58
58
  "path": "framework/press",
59
59
  "deps": []
60
60
  },
61
61
  "@uniweb/runtime": {
62
- "version": "0.8.2",
62
+ "version": "0.8.3",
63
63
  "path": "framework/runtime",
64
64
  "deps": [
65
65
  "@uniweb/core",
@@ -77,12 +77,12 @@
77
77
  "deps": []
78
78
  },
79
79
  "@uniweb/semantic-parser": {
80
- "version": "1.1.9",
80
+ "version": "1.1.10",
81
81
  "path": "framework/semantic-parser",
82
82
  "deps": []
83
83
  },
84
84
  "@uniweb/templates": {
85
- "version": "0.7.33",
85
+ "version": "0.7.34",
86
86
  "path": "framework/templates",
87
87
  "deps": []
88
88
  },
@@ -15,7 +15,7 @@ import { filterCmd } from './pm.js'
15
15
  // ── Platform URLs ──────────────────────────────────────────────
16
16
 
17
17
  // Production defaults — regular users get these out of the box
18
- const PRODUCTION_BACKEND_URL = 'https://uniweb.app'
18
+ const PRODUCTION_BACKEND_URL = 'https://hub.uniweb.app'
19
19
  const PRODUCTION_REGISTRY_URL = 'https://site-router.uniweb-edge.workers.dev'
20
20
 
21
21
  /**