Skip to content

Commit cac469e

Browse files
zrosenbauerclaude
andauthored
fix(packages/cli,deps): fix EMFILE error and upgrade to zod 4.x and type-fest 5.x (#27)
* fix(packages/cli,deps): fix EMFILE error and upgrade to zod 4.x and type-fest 5.x - Fix EMFILE (too many open files) error on macOS by adding depth limit to chokidar - Improve watcher output to show only first 3 paths + count instead of listing all paths - Upgrade zod to 4.3.6 (from 3.24.1) with compatibility fixes for new API - Upgrade type-fest to 5.4.4 (from 4.30.0) - Upgrade turbo to 2.8.17 - Add zod and type-fest to pnpm workspace catalog for consistency - Fix Zod 4.x API changes: errors -> issues, tuple syntax, record signature - Replace forEach with map to comply with functional programming rules Co-Authored-By: Claude <noreply@anthropic.com> * feat(packages/ui): inline critical CSS to prevent FOUC Fixes Flash of Unstyled Content (FOUC) by injecting minified critical CSS directly into HTML <head> during build. Critical CSS includes essential color variables and html/body background styling for immediate first paint, while full CSS loads asynchronously. Changes: - Add critical-css.ts with minified theme-specific critical CSS - Update config.ts to inject critical CSS via Rspress head config - Support all built-in themes (base, midnight, arcade, arcade-fx) Impact: - Eliminates ~100-300ms white flash on cold page loads - Improves first paint experience on production deployments - ~1KB inline CSS per theme Co-Authored-By: Claude <noreply@anthropic.com> * fix(packages/config): address PR review feedback Fixes multiple schema and compatibility issues identified in PR review: 1. **Zod v3 compatibility**: Change to `import { z } from 'zod/v3'` for compatibility with zod-to-json-schema@3.25.1, which requires Zod v3 schema objects. Redefined theme schema inline to avoid type conflicts. 2. **ConfigErrorType documentation**: Updated README to include all error types (missing_field, invalid_entry, invalid_section, invalid_field, invalid_icon, invalid_theme, duplicate_prefix, unknown). 3. **Schema strictness fixes**: - Changed frontmatter.head to use tuple for fixed positions: `z.tuple([z.string(), z.record(z.string(), z.string())])` - Changed outline to use tuple instead of array for fixed positions - Added deprecated fields (titleFrom, titleTransform) to entrySchema for backward compatibility with existing configs All packages build successfully and pass type checks. Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent b6c1d2a commit cac469e

48 files changed

Lines changed: 1187 additions & 625 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.changeset/config-theme-packages.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,15 @@
1010
This release introduces two new packages that refactor configuration and theme management:
1111

1212
**@zpress/theme** - Theme definitions and utilities
13+
1314
- Type-safe theme definitions with `LiteralUnion` pattern for autocomplete + extensibility
1415
- Built-in themes: `base`, `midnight`, `arcade`, `arcade-fx`
1516
- Icon color types with autocomplete support
1617
- Zod schemas for theme validation
1718
- Utility functions: `resolveDefaultColorMode`, `isBuiltInTheme`, `isBuiltInIconColor`
1819

1920
**@zpress/config** - Configuration loading and validation
21+
2022
- Multi-format config support: `.ts`, `.js`, `.json`, `.jsonc`, `.yml`, `.yaml`
2123
- Type-safe `defineConfig` helper
2224
- `loadConfig` function with Result-based error handling
@@ -25,12 +27,14 @@ This release introduces two new packages that refactor configuration and theme m
2527
- Re-exports theme utilities for convenience
2628

2729
**@zpress/core** - Internal refactoring
30+
2831
- Removed direct `c12` dependency
2932
- Now re-exports config and theme utilities from `@zpress/config`
3033
- Public API remains backwards compatible
3134
- Added new exports: `ICON_COLORS`, `ConfigErrorType`, `LoadConfigOptions`
3235

3336
**@zpress/ui** - Dependency updates
37+
3438
- Removed `@zpress/core` dependency for config types
3539
- Now uses `@zpress/config` and `@zpress/theme` directly
3640
- Added support for custom themes with fallback to 'toggle' color mode
@@ -41,14 +45,15 @@ This release introduces two new packages that refactor configuration and theme m
4145
For most users, this is a drop-in replacement with no migration needed. All existing imports from `@zpress/core` continue to work.
4246

4347
If you were importing from internal paths, update as follows:
48+
4449
```ts
4550
// Before
4651
import type { ThemeConfig } from '@zpress/core/theme'
4752

4853
// After
4954
import type { ThemeConfig } from '@zpress/config'
5055
// or
51-
import type { ThemeConfig } from '@zpress/core' // still works via re-export
56+
import type { ThemeConfig } from '@zpress/core' // still works via re-export
5257
```
5358
5459
**JSON/YAML Config Support**
@@ -81,7 +86,7 @@ import { defineConfig } from '@zpress/config'
8186
8287
export default defineConfig({
8388
theme: {
84-
name: 'my-custom-theme', // ✓ TypeScript accepts this
89+
name: 'my-custom-theme', // ✓ TypeScript accepts this
8590
colorMode: 'dark',
8691
},
8792
})

.changeset/refactor-workspace-config-api.md

Lines changed: 90 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
---
2-
"@zpress/core": major
3-
"@zpress/ui": major
4-
"@zpress/cli": major
5-
"@zpress/kit": major
2+
'@zpress/core': major
3+
'@zpress/ui': major
4+
'@zpress/cli': major
5+
'@zpress/kit': major
66
---
77

88
# Comprehensive Config API Refactor
@@ -30,10 +30,18 @@ interface Entry {
3030
readonly description?: string
3131
}
3232

33-
interface Section extends Entry { /* ... */ }
34-
interface Workspace extends Entry { /* ... */ }
35-
interface WorkspaceCategory extends Entry { /* ... */ }
36-
interface Feature extends Entry { /* ... */ }
33+
interface Section extends Entry {
34+
/* ... */
35+
}
36+
interface Workspace extends Entry {
37+
/* ... */
38+
}
39+
interface WorkspaceCategory extends Entry {
40+
/* ... */
41+
}
42+
interface Feature extends Entry {
43+
/* ... */
44+
}
3745
```
3846

3947
### Workspace Field Changes
@@ -42,32 +50,44 @@ interface Feature extends Entry { /* ... */ }
4250

4351
```ts
4452
// Before
45-
apps: [{
46-
title: 'API',
47-
path: '/apps/api',
48-
}]
53+
apps: [
54+
{
55+
title: 'API',
56+
path: '/apps/api',
57+
},
58+
]
4959

5060
// After
51-
apps: [{
52-
title: 'API',
53-
prefix: '/apps/api',
54-
}]
61+
apps: [
62+
{
63+
title: 'API',
64+
prefix: '/apps/api',
65+
},
66+
]
5567
```
5668

5769
**`name``title`** on `WorkspaceCategory`: All types now use `title` consistently
5870

5971
```ts
6072
// Before
61-
workspaces: [{
62-
name: 'Integrations',
63-
items: [/* ... */],
64-
}]
73+
workspaces: [
74+
{
75+
name: 'Integrations',
76+
items: [
77+
/* ... */
78+
],
79+
},
80+
]
6581

6682
// After
67-
workspaces: [{
68-
title: 'Integrations',
69-
items: [/* ... */],
70-
}]
83+
workspaces: [
84+
{
85+
title: 'Integrations',
86+
items: [
87+
/* ... */
88+
],
89+
},
90+
]
7191
```
7292

7393
### Discovery Configuration
@@ -76,26 +96,30 @@ Workspace items now use a `discovery` field to configure content auto-discovery,
7696

7797
```ts
7898
// Before
79-
apps: [{
80-
title: 'API',
81-
path: '/apps/api',
82-
from: 'docs/*.md',
83-
titleFrom: 'frontmatter',
84-
sort: 'alpha',
85-
recursive: false,
86-
}]
87-
88-
// After
89-
apps: [{
90-
title: 'API',
91-
prefix: '/apps/api',
92-
discovery: {
99+
apps: [
100+
{
101+
title: 'API',
102+
path: '/apps/api',
93103
from: 'docs/*.md',
94-
title: { from: 'auto' },
104+
titleFrom: 'frontmatter',
95105
sort: 'alpha',
96106
recursive: false,
97107
},
98-
}]
108+
]
109+
110+
// After
111+
apps: [
112+
{
113+
title: 'API',
114+
prefix: '/apps/api',
115+
discovery: {
116+
from: 'docs/*.md',
117+
title: { from: 'auto' },
118+
sort: 'alpha',
119+
recursive: false,
120+
},
121+
},
122+
]
99123
```
100124

101125
**Note**: The `from` field in `discovery` is relative to the workspace's base path (derived from `prefix`). For example, `prefix: "/apps/api"` + `discovery.from: "docs/*.md"` resolves to `apps/api/docs/*.md` (repo-root relative).
@@ -105,6 +129,7 @@ apps: [{
105129
**Default `titleFrom` changed from `'filename'` to `'auto'`**
106130

107131
The `'auto'` strategy uses a smart fallback chain:
132+
108133
1. Try frontmatter `title` field
109134
2. Fall back to first `# heading`
110135
3. Fall back to filename (kebab-to-title)
@@ -142,13 +167,14 @@ interface Discovery {
142167
exclude?: GlobPattern[]
143168
frontmatter?: Frontmatter
144169
recursive?: boolean
145-
indexFile?: string // Only when recursive: true
170+
indexFile?: string // Only when recursive: true
146171
}
147172
```
148173

149174
### Enhanced Icon Documentation
150175

151176
Icon colors are now fully documented in types with the 8-color palette rotation:
177+
152178
- purple (default)
153179
- blue
154180
- green
@@ -163,18 +189,21 @@ Icon colors are now fully documented in types with the 8-color palette rotation:
163189
### Automated Find/Replace
164190

165191
1. **Update workspace field names**:
192+
166193
```
167194
Find: path: '/
168195
Replace: prefix: '/
169196
```
170197

171198
2. **Update workspace group names**:
199+
172200
```
173201
Find: name: '
174202
Replace: title: '
175203
```
176204

177205
3. **Update type imports** (if using types directly):
206+
178207
```ts
179208
// Before
180209
import type { Entry, WorkspaceItem, WorkspaceGroup } from '@zpress/core'
@@ -189,24 +218,28 @@ Icon colors are now fully documented in types with the 8-color palette rotation:
189218

190219
```ts
191220
// Before
192-
apps: [{
193-
title: 'API',
194-
path: '/apps/api',
195-
from: 'docs/*.md',
196-
titleFrom: 'frontmatter',
197-
sort: 'alpha',
198-
}]
199-
200-
// After
201-
apps: [{
202-
title: 'API',
203-
prefix: '/apps/api',
204-
discovery: {
221+
apps: [
222+
{
223+
title: 'API',
224+
path: '/apps/api',
205225
from: 'docs/*.md',
206-
title: { from: 'auto' }, // Better default!
226+
titleFrom: 'frontmatter',
207227
sort: 'alpha',
208228
},
209-
}]
229+
]
230+
231+
// After
232+
apps: [
233+
{
234+
title: 'API',
235+
prefix: '/apps/api',
236+
discovery: {
237+
from: 'docs/*.md',
238+
title: { from: 'auto' }, // Better default!
239+
sort: 'alpha',
240+
},
241+
},
242+
]
210243
```
211244

212245
2. **Verify title derivation behavior**: If you have sections with `titleFrom: 'filename'` and markdown files with frontmatter or headings, the default `'auto'` mode will now use those instead of the filename. To preserve old behavior, explicitly set `titleFrom: 'filename'`.
@@ -220,6 +253,7 @@ Icon colors are now fully documented in types with the 8-color palette rotation:
220253
## Documentation
221254

222255
See updated guides:
256+
223257
- [Workspaces](/guides/workspaces) - New `prefix` and `discovery` fields
224258
- [Auto-Discovery](/guides/auto-discovery) - New `'auto'` titleFrom mode and `TitleConfig`
225259
- [Configuration Reference](/reference/configuration) - Full field reference
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
"@zpress/ui": patch
2+
'@zpress/ui': patch
33
---
44

55
Add VS Code mode improvements: hide mobile navigation elements and scope all VS Code overrides to `html[data-zpress-env="vscode"]` selector for cleaner CSS without !important rules.
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
{
22
"folders": [
33
{
4-
"path": "../examples/kitchen-sink"
5-
}
4+
"path": "../examples/kitchen-sink",
5+
},
66
],
7-
"settings": {}
7+
"settings": {},
88
}

.vscode/settings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,4 @@
1919
"titleBar.inactiveForeground": "#15202b99"
2020
},
2121
"peacock.color": "#9f9f03"
22-
}
22+
}

.vscode/simple.code-workspace

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
{
22
"folders": [
33
{
4-
"path": "../examples/simple"
5-
}
4+
"path": "../examples/simple",
5+
},
66
],
7-
"settings": {}
7+
"settings": {},
88
}

docs/guides/workspaces.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,15 +58,15 @@ export default defineConfig({
5858

5959
## Fields
6060

61-
| Field | Type | Required | Description |
62-
| ------------- | ------------------------------ | -------- | --------------------------------------------------------------- |
63-
| `title` | `string` | yes | Display name |
61+
| Field | Type | Required | Description |
62+
| ------------- | ------------------------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
63+
| `title` | `string` | yes | Display name |
6464
| `icon` | `IconConfig` | no | Icon ID string (from bundled collections) or `{ id: IconId, color: IconColor }` object. See [icon reference](/references/icons/overview) for supported icons. |
65-
| `description` | `string` | yes | Short description for cards |
66-
| `tags` | `string[]` | no | Technology tags (kebab-case) |
67-
| `badge` | `{ src: string; alt: string }` | no | Deploy badge image |
68-
| `prefix` | `string` | yes | URL prefix for this workspace's documentation |
69-
| `discovery` | `Discovery` | no | Content discovery configuration (glob, title, sort, etc.) |
65+
| `description` | `string` | yes | Short description for cards |
66+
| `tags` | `string[]` | no | Technology tags (kebab-case) |
67+
| `badge` | `{ src: string; alt: string }` | no | Deploy badge image |
68+
| `prefix` | `string` | yes | URL prefix for this workspace's documentation |
69+
| `discovery` | `Discovery` | no | Content discovery configuration (glob, title, sort, etc.) |
7070

7171
## How it works
7272

0 commit comments

Comments
 (0)