polen 0.9.0-next.3 → 0.9.0-next.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/build/api/server/report-error.d.ts +2 -0
- package/build/api/server/report-error.d.ts.map +1 -0
- package/build/api/server/report-error.js +47 -0
- package/build/api/server/report-error.js.map +1 -0
- package/build/api/vite/data/navbar.d.ts +9 -0
- package/build/api/vite/data/navbar.d.ts.map +1 -0
- package/build/api/vite/data/navbar.js +6 -0
- package/build/api/vite/data/navbar.js.map +1 -0
- package/build/api/vite/plugins/core.d.ts.map +1 -1
- package/build/api/vite/plugins/core.js +36 -104
- package/build/api/vite/plugins/core.js.map +1 -1
- package/build/api/vite/plugins/pages.d.ts +12 -3
- package/build/api/vite/plugins/pages.d.ts.map +1 -1
- package/build/api/vite/plugins/pages.js +155 -35
- package/build/api/vite/plugins/pages.js.map +1 -1
- package/build/api/vite/plugins/serve.d.ts.map +1 -1
- package/build/api/vite/plugins/serve.js +5 -26
- package/build/api/vite/plugins/serve.js.map +1 -1
- package/build/cli/commands/dev.js +9 -1
- package/build/cli/commands/dev.js.map +1 -1
- package/build/lib/debug/environment-variable.d.ts +1 -0
- package/build/lib/debug/environment-variable.d.ts.map +1 -1
- package/build/lib/debug/environment-variable.js +30 -15
- package/build/lib/debug/environment-variable.js.map +1 -1
- package/build/lib/extensible-data/extensible-data.d.ts +17 -0
- package/build/lib/extensible-data/extensible-data.d.ts.map +1 -0
- package/build/lib/extensible-data/extensible-data.js +24 -0
- package/build/lib/extensible-data/extensible-data.js.map +1 -0
- package/build/lib/extensible-data/index.d.ts +2 -0
- package/build/lib/extensible-data/index.d.ts.map +1 -0
- package/build/lib/extensible-data/index.js +2 -0
- package/build/lib/extensible-data/index.js.map +1 -0
- package/build/lib/kit-temp.d.ts +2 -0
- package/build/lib/kit-temp.d.ts.map +1 -1
- package/build/lib/kit-temp.js +10 -1
- package/build/lib/kit-temp.js.map +1 -1
- package/build/lib/react-router-loader/react-router-loader.d.ts.map +1 -1
- package/build/lib/react-router-loader/react-router-loader.js +0 -1
- package/build/lib/react-router-loader/react-router-loader.js.map +1 -1
- package/build/lib/vite-plugin-json/index.d.ts +2 -0
- package/build/lib/vite-plugin-json/index.d.ts.map +1 -0
- package/build/lib/vite-plugin-json/index.js +2 -0
- package/build/lib/vite-plugin-json/index.js.map +1 -0
- package/build/lib/vite-plugin-json/vite-plugin-json.d.ts +64 -0
- package/build/lib/vite-plugin-json/vite-plugin-json.d.ts.map +1 -0
- package/build/lib/vite-plugin-json/vite-plugin-json.js +59 -0
- package/build/lib/vite-plugin-json/vite-plugin-json.js.map +1 -0
- package/build/lib/vite-plugin-reactive-data/index.d.ts +2 -0
- package/build/lib/vite-plugin-reactive-data/index.d.ts.map +1 -0
- package/build/lib/vite-plugin-reactive-data/index.js +2 -0
- package/build/lib/vite-plugin-reactive-data/index.js.map +1 -0
- package/build/lib/vite-plugin-reactive-data/vite-plugin-reactive-data.d.ts +39 -0
- package/build/lib/vite-plugin-reactive-data/vite-plugin-reactive-data.d.ts.map +1 -0
- package/build/lib/vite-plugin-reactive-data/vite-plugin-reactive-data.js +92 -0
- package/build/lib/vite-plugin-reactive-data/vite-plugin-reactive-data.js.map +1 -0
- package/build/lib/vite-plugins/build-logger.d.ts.map +1 -1
- package/build/lib/vite-plugins/build-logger.js +9 -8
- package/build/lib/vite-plugins/build-logger.js.map +1 -1
- package/build/project-data.d.ts +0 -11
- package/build/project-data.d.ts.map +1 -1
- package/build/template/components/Link.d.ts.map +1 -1
- package/build/template/components/Link.jsx +4 -3
- package/build/template/components/Link.jsx.map +1 -1
- package/build/template/routes/changelog.jsx +1 -1
- package/build/template/routes/changelog.jsx.map +1 -1
- package/build/template/routes/reference.jsx +1 -1
- package/build/template/routes/reference.jsx.map +1 -1
- package/build/template/routes/root.d.ts.map +1 -1
- package/build/template/routes/root.jsx +5 -3
- package/build/template/routes/root.jsx.map +1 -1
- package/build/template/server/app.js +1 -1
- package/build/template/server/app.js.map +1 -1
- package/build/template/server/render-page.d.ts.map +1 -1
- package/build/template/server/render-page.jsx +4 -1
- package/build/template/server/render-page.jsx.map +1 -1
- package/build/template/server/ssg/generate.js +1 -1
- package/build/template/server/ssg/generate.js.map +1 -1
- package/build/template/server/ssg/get-route-paths.js +1 -1
- package/build/template/server/ssg/get-route-paths.js.map +1 -1
- package/package.json +2 -1
- package/src/api/server/report-error.ts +61 -0
- package/src/api/vite/data/navbar.ts +15 -0
- package/src/api/vite/plugins/core.ts +38 -116
- package/src/api/vite/plugins/pages.ts +185 -40
- package/src/api/vite/plugins/serve.ts +5 -26
- package/src/cli/commands/dev.ts +9 -1
- package/src/lib/debug/environment-variable.ts +31 -14
- package/src/lib/extensible-data/extensible-data.ts +38 -0
- package/src/lib/extensible-data/index.ts +1 -0
- package/src/lib/kit-temp.ts +12 -1
- package/src/lib/react-router-loader/react-router-loader.ts +0 -1
- package/src/lib/vite-plugin-json/index.ts +1 -0
- package/src/lib/vite-plugin-json/vite-plugin-json.ts +128 -0
- package/src/lib/vite-plugin-reactive-data/index.ts +1 -0
- package/src/lib/vite-plugin-reactive-data/vite-plugin-reactive-data.ts +131 -0
- package/src/lib/vite-plugins/build-logger.ts +10 -8
- package/src/project-data.ts +0 -13
- package/src/template/components/Link.tsx +6 -3
- package/src/template/routes/changelog.tsx +1 -1
- package/src/template/routes/reference.tsx +1 -1
- package/src/template/routes/root.tsx +5 -3
- package/src/template/server/app.ts +1 -1
- package/src/template/server/render-page.tsx +4 -1
- package/src/template/server/ssg/generate.ts +1 -1
- package/src/template/server/ssg/get-route-paths.ts +1 -1
@@ -1,38 +1,32 @@
|
|
1
1
|
import type { Config } from '#api/config/index'
|
2
|
+
import { NavbarData } from '#api/vite/data/navbar'
|
2
3
|
import { VitePluginSelfContainedMode } from '#cli/_/self-contained-mode'
|
3
4
|
import type { ReactRouter } from '#dep/react-router/index'
|
4
5
|
import type { Vite } from '#dep/vite/index'
|
5
|
-
import {
|
6
|
-
import {
|
7
|
-
import { Tree } from '#lib/tree/index'
|
6
|
+
import { VitePluginJson } from '#lib/vite-plugin-json/index'
|
7
|
+
import { VitePluginReactiveData } from '#lib/vite-plugin-reactive-data/index'
|
8
8
|
import { ViteVirtual } from '#lib/vite-virtual/index'
|
9
9
|
import { debug } from '#singletons/debug'
|
10
|
+
import { superjson } from '#singletons/superjson'
|
10
11
|
import { Json, Str } from '@wollybeard/kit'
|
11
|
-
import
|
12
|
-
import type { ProjectData, SidebarIndex, SiteNavigationItem } from '../../../project-data.ts'
|
13
|
-
import { superjson } from '../../../singletons/superjson.ts'
|
12
|
+
import type { ProjectData } from '../../../project-data.ts'
|
14
13
|
import { SchemaAugmentation } from '../../schema-augmentation/index.ts'
|
15
14
|
import { Schema } from '../../schema/index.ts'
|
16
15
|
import { createLogger } from '../logger.ts'
|
17
16
|
import { polenVirtual } from '../vi.ts'
|
18
|
-
import {
|
17
|
+
import { Pages } from './pages.ts'
|
19
18
|
|
20
19
|
const _debug = debug.sub(`vite-plugin-core`)
|
21
20
|
|
22
21
|
const viTemplateVariables = polenVirtual([`template`, `variables`])
|
23
22
|
const viTemplateSchemaAugmentations = polenVirtual([`template`, `schema-augmentations`])
|
24
|
-
const viProjectData = polenVirtual([`project`, `data`])
|
23
|
+
const viProjectData = polenVirtual([`project`, `data.jsonsuper`], { allowPluginProcessing: true })
|
25
24
|
|
26
25
|
export interface ProjectPagesModule {
|
27
26
|
pages: ReactRouter.RouteObject[]
|
28
27
|
}
|
29
28
|
|
30
29
|
export const Core = (config: Config.Config): Vite.PluginOption[] => {
|
31
|
-
// State for current pages data (updated by pages plugin)
|
32
|
-
let currentPagesData: FileRouter.ScanResult | null = null
|
33
|
-
let currentTreeData: FileRouter.RouteTreeNode | null = null
|
34
|
-
let viteDevServer: Vite.ViteDevServer | null = null
|
35
|
-
|
36
30
|
// Schema cache management
|
37
31
|
let schemaCache: Awaited<ReturnType<typeof Schema.readOrThrow>> | null = null
|
38
32
|
|
@@ -52,6 +46,7 @@ export const Core = (config: Config.Config): Vite.PluginOption[] => {
|
|
52
46
|
}
|
53
47
|
|
54
48
|
const plugins: Vite.Plugin[] = []
|
49
|
+
const navbarData = NavbarData()
|
55
50
|
|
56
51
|
// Note: The main use for this right now is to resolve the react imports
|
57
52
|
// from the mdx vite plugin which have to go through the Polen exports since Polen keeps those deps bundled.
|
@@ -64,26 +59,19 @@ export const Core = (config: Config.Config): Vite.PluginOption[] => {
|
|
64
59
|
}))
|
65
60
|
}
|
66
61
|
|
62
|
+
const json = VitePluginJson.create({
|
63
|
+
codec: {
|
64
|
+
validate: superjson,
|
65
|
+
importPath: import.meta.resolve('#singletons/superjson'),
|
66
|
+
importExport: 'superjson',
|
67
|
+
},
|
68
|
+
filter: {
|
69
|
+
moduleTypes: ['jsonsuper'],
|
70
|
+
},
|
71
|
+
})
|
72
|
+
|
67
73
|
return [
|
68
74
|
...plugins,
|
69
|
-
|
70
|
-
// Self-contained pages plugin
|
71
|
-
...createPagesPlugin({
|
72
|
-
config,
|
73
|
-
onPagesChange: (pages) => {
|
74
|
-
currentPagesData = pages
|
75
|
-
// Invalidate project data virtual module to regenerate navigation/sidebar
|
76
|
-
if (viteDevServer) {
|
77
|
-
const projectDataModule = viteDevServer.moduleGraph.getModuleById(viProjectData.resolved)
|
78
|
-
if (projectDataModule) {
|
79
|
-
viteDevServer.moduleGraph.invalidateModule(projectDataModule)
|
80
|
-
}
|
81
|
-
}
|
82
|
-
},
|
83
|
-
onTreeChange: (tree) => {
|
84
|
-
currentTreeData = tree
|
85
|
-
},
|
86
|
-
}),
|
87
75
|
/**
|
88
76
|
* If a `polen*` import is encountered from the user's project, resolve it to the currently
|
89
77
|
* running source code of Polen rather than the user's node_modules.
|
@@ -95,9 +83,9 @@ export const Core = (config: Config.Config): Vite.PluginOption[] => {
|
|
95
83
|
* 2. Secondary: Using Polen CLI on a project that does not have Polen installed.
|
96
84
|
* (User would likely not want to do this because they would not be able to achieve type safety)
|
97
85
|
*/
|
98
|
-
|
99
86
|
{
|
100
87
|
name: `polen:internal-import-alias`,
|
88
|
+
enforce: 'pre' as const,
|
101
89
|
resolveId(id, importer) {
|
102
90
|
const d = debug.sub(`vite-plugin:internal-import-alias`)
|
103
91
|
|
@@ -133,11 +121,20 @@ export const Core = (config: Config.Config): Vite.PluginOption[] => {
|
|
133
121
|
return to
|
134
122
|
},
|
135
123
|
},
|
124
|
+
json,
|
125
|
+
VitePluginReactiveData.create({
|
126
|
+
moduleId: `virtual:polen/project/data/navbar`,
|
127
|
+
data: navbarData.value,
|
128
|
+
codec: superjson,
|
129
|
+
name: `polen-navbar`,
|
130
|
+
moduleType: 'jsonsuper',
|
131
|
+
}),
|
132
|
+
...Pages({
|
133
|
+
config,
|
134
|
+
navbarData,
|
135
|
+
}),
|
136
136
|
{
|
137
137
|
name: `polen:core`,
|
138
|
-
configureServer(server) {
|
139
|
-
viteDevServer = server
|
140
|
-
},
|
141
138
|
config(_, { command }) {
|
142
139
|
// isServing = command === `serve`
|
143
140
|
return {
|
@@ -187,81 +184,15 @@ export const Core = (config: Config.Config): Vite.PluginOption[] => {
|
|
187
184
|
identifier: viProjectData,
|
188
185
|
async loader() {
|
189
186
|
_debug(`loadingViProjectDataVirtualModule`)
|
190
|
-
// todo: parallel
|
191
187
|
const schema = await readSchema()
|
192
188
|
|
193
|
-
// Get pages data from the pages plugin or load initially
|
194
|
-
if (!currentPagesData) {
|
195
|
-
_debug(`loadingPagesDataInitially`)
|
196
|
-
currentPagesData = await FileRouter.scan({
|
197
|
-
dir: config.paths.project.absolute.pages,
|
198
|
-
glob: `**/*.{md,mdx}`,
|
199
|
-
})
|
200
|
-
// Report any diagnostics from initial scan
|
201
|
-
reportDiagnostics(currentPagesData.diagnostics)
|
202
|
-
}
|
203
|
-
if (!currentTreeData) {
|
204
|
-
_debug(`loadingTreeDataInitially`)
|
205
|
-
currentTreeData = await getRouteTree(config)
|
206
|
-
}
|
207
|
-
const pagesScanResult = currentPagesData
|
208
|
-
const routeTree = currentTreeData
|
209
|
-
_debug(`usingPageRoutesFromPagesPlugin`, pagesScanResult.routes.length)
|
210
|
-
|
211
|
-
const siteNavigationItems: SiteNavigationItem[] = []
|
212
|
-
|
213
|
-
//
|
214
|
-
// ━━ Build Navbar
|
215
|
-
//
|
216
|
-
|
217
|
-
// Process first-level children as navigation items
|
218
|
-
for (const child of routeTree.children) {
|
219
|
-
if (child.value.type === 'directory') {
|
220
|
-
// Check if this directory has an index file
|
221
|
-
const hasIndex = child.children.some(c => c.value.type === 'file' && c.value.name === 'index')
|
222
|
-
|
223
|
-
if (hasIndex) {
|
224
|
-
const pathExp = FileRouter.pathToExpression([child.value.name])
|
225
|
-
const title = Str.titlizeSlug(child.value.name)
|
226
|
-
siteNavigationItems.push({
|
227
|
-
pathExp: pathExp.startsWith('/') ? pathExp.slice(1) : pathExp,
|
228
|
-
title,
|
229
|
-
})
|
230
|
-
}
|
231
|
-
} else if (child.value.type === 'file' && child.value.name !== 'index') {
|
232
|
-
const pathExp = FileRouter.pathToExpression([child.value.name])
|
233
|
-
const title = Str.titlizeSlug(child.value.name)
|
234
|
-
siteNavigationItems.push({
|
235
|
-
pathExp: pathExp.startsWith('/') ? pathExp.slice(1) : pathExp,
|
236
|
-
title,
|
237
|
-
})
|
238
|
-
}
|
239
|
-
}
|
240
|
-
|
241
189
|
// ━ Schema presence causes adding some navbar items
|
190
|
+
const schemaNavbar = navbarData.get('schema')
|
191
|
+
schemaNavbar.length = 0 // Clear existing
|
242
192
|
if (schema) {
|
243
|
-
|
193
|
+
schemaNavbar.push({ pathExp: `reference`, title: `Reference` })
|
244
194
|
if (schema.versions.length > 1) {
|
245
|
-
|
246
|
-
}
|
247
|
-
}
|
248
|
-
|
249
|
-
//
|
250
|
-
// ━━ Build Sidebar
|
251
|
-
//
|
252
|
-
|
253
|
-
const sidebarIndex: SidebarIndex = {}
|
254
|
-
|
255
|
-
// Build sidebar for each top-level directory
|
256
|
-
for (const child of routeTree.children) {
|
257
|
-
if (child.value.type === 'directory') {
|
258
|
-
const pathExp = `/${child.value.name}`
|
259
|
-
// Create a subtree starting from this directory
|
260
|
-
const subtree = Tree.node(child.value, child.children)
|
261
|
-
// Pass the directory name as base path so paths are built correctly
|
262
|
-
const sidebar = FileRouter.Sidebar.buildFromTree(subtree, [child.value.name])
|
263
|
-
_debug(`Built sidebar for ${pathExp}:`, sidebar)
|
264
|
-
sidebarIndex[pathExp] = sidebar
|
195
|
+
schemaNavbar.push({ pathExp: `changelog`, title: `Changelog` })
|
265
196
|
}
|
266
197
|
}
|
267
198
|
|
@@ -271,10 +202,7 @@ export const Core = (config: Config.Config): Vite.PluginOption[] => {
|
|
271
202
|
|
272
203
|
const projectData: ProjectData = {
|
273
204
|
schema,
|
274
|
-
siteNavigationItems,
|
275
|
-
sidebarIndex,
|
276
205
|
faviconPath: `/logo.svg`,
|
277
|
-
pagesScanResult: pagesScanResult,
|
278
206
|
paths: config.paths.project,
|
279
207
|
server: {
|
280
208
|
static: {
|
@@ -288,14 +216,8 @@ export const Core = (config: Config.Config): Vite.PluginOption[] => {
|
|
288
216
|
},
|
289
217
|
}
|
290
218
|
|
291
|
-
|
292
|
-
|
293
|
-
import { superjson } from '#singletons/superjson'
|
294
|
-
|
295
|
-
export const PROJECT_DATA = superjson.parse('${projectDataCode}')
|
296
|
-
`
|
297
|
-
|
298
|
-
return content
|
219
|
+
// Return just the JSON string - let the JSON plugin handle the transformation
|
220
|
+
return superjson.stringify(projectData)
|
299
221
|
},
|
300
222
|
},
|
301
223
|
),
|
@@ -1,10 +1,12 @@
|
|
1
1
|
import type { Config } from '#api/config/index'
|
2
|
+
import type { NavbarDataRegistry } from '#api/vite/data/navbar'
|
2
3
|
import { polenVirtual } from '#api/vite/vi'
|
3
4
|
import type { Vite } from '#dep/vite/index'
|
4
5
|
import { reportDiagnostics } from '#lib/file-router/diagnostic-reporter'
|
5
6
|
import { FileRouter } from '#lib/file-router/index'
|
6
|
-
import {
|
7
|
+
import { Tree } from '#lib/tree/index'
|
7
8
|
import { debug } from '#singletons/debug'
|
9
|
+
import { superjson } from '#singletons/superjson'
|
8
10
|
import mdx from '@mdx-js/rollup'
|
9
11
|
import { Path, Str } from '@wollybeard/kit'
|
10
12
|
import remarkGfm from 'remark-gfm'
|
@@ -12,19 +14,36 @@ import remarkGfm from 'remark-gfm'
|
|
12
14
|
const _debug = debug.sub(`vite-plugin-pages`)
|
13
15
|
|
14
16
|
export const viProjectPages = polenVirtual([`project`, `pages.jsx`], { allowPluginProcessing: true })
|
17
|
+
export const viProjectPagesData = polenVirtual([`project`, `data`, 'pages.jsonsuper'], { allowPluginProcessing: true })
|
15
18
|
|
16
19
|
export interface PagesTreePluginOptions {
|
17
20
|
config: Config.Config
|
21
|
+
navbarData?: NavbarDataRegistry
|
18
22
|
onPagesChange?: (pages: FileRouter.ScanResult) => void
|
19
23
|
onTreeChange?: (tree: FileRouter.RouteTreeNode) => void
|
20
24
|
}
|
21
25
|
|
26
|
+
export interface ProjectDataPages {
|
27
|
+
sidebarIndex: SidebarIndex
|
28
|
+
pagesScanResult: FileRouter.ScanResult
|
29
|
+
}
|
30
|
+
|
31
|
+
export interface SidebarIndex {
|
32
|
+
[pathExpression: string]: FileRouter.Sidebar.Sidebar
|
33
|
+
}
|
34
|
+
|
22
35
|
/**
|
23
36
|
* Pages plugin with tree support
|
24
37
|
*/
|
25
|
-
export const
|
26
|
-
|
27
|
-
|
38
|
+
export const Pages = ({
|
39
|
+
config,
|
40
|
+
navbarData,
|
41
|
+
onPagesChange,
|
42
|
+
onTreeChange,
|
43
|
+
}: PagesTreePluginOptions): Vite.Plugin[] => {
|
44
|
+
let currentPagesData: FileRouter.ScanResult | null = null
|
45
|
+
let currentTreeData: FileRouter.RouteTreeNode | null = null
|
46
|
+
|
28
47
|
// State management
|
29
48
|
let pagesCache: FileRouter.ScanResult | null = null
|
30
49
|
let treeCache: FileRouter.RouteTreeNode | null = null
|
@@ -119,60 +138,186 @@ export const createPagesPlugin = (
|
|
119
138
|
},
|
120
139
|
|
121
140
|
// Hot update handling
|
122
|
-
async handleHotUpdate({ file, server }) {
|
141
|
+
async handleHotUpdate({ file, server, modules }) {
|
123
142
|
_debug(`handleHotUpdate`, file)
|
124
143
|
if (!isPageFile(file)) return
|
125
144
|
|
126
145
|
_debug(`Page file changed:`, file)
|
127
146
|
|
128
|
-
//
|
147
|
+
// Check if this is a content-only change to an existing page
|
148
|
+
const oldPages = pagesCache
|
149
|
+
|
150
|
+
// Clear cache and rescan
|
129
151
|
clearCache()
|
152
|
+
const newPages = await scanPages()
|
153
|
+
currentPagesData = newPages
|
130
154
|
|
131
|
-
//
|
132
|
-
const
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
155
|
+
// Check if page structure changed (added/removed pages)
|
156
|
+
const structureChanged = !oldPages
|
157
|
+
|| oldPages.routes.length !== newPages.routes.length
|
158
|
+
|| !oldPages.routes.every((oldRoute, i) =>
|
159
|
+
oldRoute.file.path.absolute === newPages.routes[i]?.file.path.absolute
|
160
|
+
)
|
137
161
|
|
138
|
-
|
139
|
-
|
140
|
-
const pages = await scanPages()
|
141
|
-
// Report any diagnostics
|
142
|
-
reportDiagnostics(pages.diagnostics)
|
143
|
-
onPagesChange(pages)
|
144
|
-
}
|
162
|
+
if (structureChanged) {
|
163
|
+
_debug(`Page structure changed, triggering full reload`)
|
145
164
|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
165
|
+
// Invalidate virtual module
|
166
|
+
const mod = server.moduleGraph.getModuleById(viProjectPages.id)
|
167
|
+
if (mod) {
|
168
|
+
server.moduleGraph.invalidateModule(mod)
|
169
|
+
_debug(`Invalidated pages virtual module`)
|
170
|
+
}
|
171
|
+
|
172
|
+
// Notify about changes
|
173
|
+
if (onPagesChange) {
|
174
|
+
reportDiagnostics(newPages.diagnostics)
|
175
|
+
onPagesChange(newPages)
|
176
|
+
}
|
177
|
+
|
178
|
+
if (onTreeChange) {
|
179
|
+
const tree = await scanTree()
|
180
|
+
onTreeChange(tree)
|
181
|
+
currentTreeData = tree
|
182
|
+
}
|
183
|
+
|
184
|
+
// Trigger full reload for structure changes
|
185
|
+
server.ws.send({ type: `full-reload` })
|
186
|
+
return []
|
187
|
+
} else {
|
188
|
+
_debug(`Page content changed, allowing HMR`)
|
189
|
+
// Let default HMR handle the MDX file change
|
190
|
+
return modules
|
191
|
+
}
|
192
|
+
},
|
193
|
+
resolveId(id) {
|
194
|
+
if (id === viProjectPagesData.id) {
|
195
|
+
return viProjectPagesData.resolved
|
150
196
|
}
|
197
|
+
},
|
198
|
+
load: {
|
199
|
+
// filter: {
|
200
|
+
// id: viProjectPagesData.resolved,
|
201
|
+
// },
|
202
|
+
async handler(id) {
|
203
|
+
if (id !== viProjectPagesData.resolved) return
|
204
|
+
_debug(`viProjectDataPages`)
|
205
|
+
|
206
|
+
// Get pages data from the pages plugin or load initially
|
207
|
+
if (!currentPagesData) {
|
208
|
+
_debug(`loadingPagesDataInitially`)
|
209
|
+
currentPagesData = await FileRouter.scan({
|
210
|
+
dir: config.paths.project.absolute.pages,
|
211
|
+
glob: `**/*.{md,mdx}`,
|
212
|
+
})
|
213
|
+
// Report any diagnostics from initial scan
|
214
|
+
reportDiagnostics(currentPagesData.diagnostics)
|
215
|
+
}
|
216
|
+
if (!currentTreeData) {
|
217
|
+
_debug(`loadingTreeDataInitially`)
|
218
|
+
currentTreeData = await getRouteTree(config)
|
219
|
+
}
|
220
|
+
const pagesScanResult = currentPagesData
|
221
|
+
const routeTree = currentTreeData
|
222
|
+
_debug(`usingPageRoutesFromPagesPlugin`, pagesScanResult.routes.length)
|
223
|
+
|
224
|
+
//
|
225
|
+
// ━━ Build Navbar
|
226
|
+
//
|
151
227
|
|
152
|
-
|
153
|
-
|
228
|
+
// Update navbar if provided
|
229
|
+
if (navbarData) {
|
230
|
+
const navbarPages = navbarData.get('pages')
|
231
|
+
navbarPages.length = 0 // Clear existing
|
154
232
|
|
155
|
-
|
233
|
+
// Process first-level children as navigation items
|
234
|
+
for (const child of routeTree.children) {
|
235
|
+
if (child.value.type === 'directory') {
|
236
|
+
// Check if this directory has an index file
|
237
|
+
const hasIndex = child.children.some(c => c.value.type === 'file' && c.value.name === 'index')
|
238
|
+
|
239
|
+
if (hasIndex) {
|
240
|
+
const pathExp = FileRouter.pathToExpression([child.value.name])
|
241
|
+
const title = Str.titlizeSlug(child.value.name)
|
242
|
+
navbarPages.push({
|
243
|
+
pathExp: pathExp.startsWith('/') ? pathExp.slice(1) : pathExp,
|
244
|
+
title,
|
245
|
+
})
|
246
|
+
}
|
247
|
+
} else if (child.value.type === 'file' && child.value.name !== 'index') {
|
248
|
+
const pathExp = FileRouter.pathToExpression([child.value.name])
|
249
|
+
const title = Str.titlizeSlug(child.value.name)
|
250
|
+
navbarPages.push({
|
251
|
+
pathExp: pathExp.startsWith('/') ? pathExp.slice(1) : pathExp,
|
252
|
+
title,
|
253
|
+
})
|
254
|
+
}
|
255
|
+
}
|
256
|
+
}
|
257
|
+
|
258
|
+
//
|
259
|
+
// ━━ Build Sidebar
|
260
|
+
//
|
261
|
+
|
262
|
+
const sidebarIndex: SidebarIndex = {}
|
263
|
+
|
264
|
+
// Build sidebar for each top-level directory
|
265
|
+
for (const child of routeTree.children) {
|
266
|
+
if (child.value.type === 'directory') {
|
267
|
+
const pathExp = `/${child.value.name}`
|
268
|
+
// Create a subtree starting from this directory
|
269
|
+
const subtree = Tree.node(child.value, child.children)
|
270
|
+
// Pass the directory name as base path so paths are built correctly
|
271
|
+
const sidebar = FileRouter.Sidebar.buildFromTree(subtree, [child.value.name])
|
272
|
+
_debug(`Built sidebar for ${pathExp}:`, sidebar)
|
273
|
+
sidebarIndex[pathExp] = sidebar
|
274
|
+
}
|
275
|
+
}
|
276
|
+
|
277
|
+
//
|
278
|
+
// ━━ Put It All together
|
279
|
+
//
|
280
|
+
|
281
|
+
const projectDataPages: ProjectDataPages = {
|
282
|
+
sidebarIndex,
|
283
|
+
pagesScanResult: pagesScanResult,
|
284
|
+
}
|
285
|
+
|
286
|
+
// Return just the JSON string - let the JSON plugin handle the transformation
|
287
|
+
return superjson.stringify(projectDataPages)
|
288
|
+
},
|
156
289
|
},
|
290
|
+
},
|
291
|
+
// Plugin 4: Virtual Module for Pages Routes
|
292
|
+
{
|
293
|
+
name: 'polen:pages:routes',
|
294
|
+
resolveId(id) {
|
295
|
+
if (id === viProjectPages.id) {
|
296
|
+
return viProjectPages.resolved
|
297
|
+
}
|
298
|
+
},
|
299
|
+
load: {
|
300
|
+
// filter: {
|
301
|
+
// id: viProjectPages.resolved,
|
302
|
+
// },
|
303
|
+
handler: async (id) => {
|
304
|
+
if (id !== viProjectPages.resolved) return
|
157
305
|
|
158
|
-
// Virtual module handling
|
159
|
-
...ViteVirtual.IdentifiedLoader.toHooks({
|
160
|
-
identifier: viProjectPages,
|
161
|
-
async loader() {
|
162
306
|
_debug(`Loading viProjectPages virtual module`)
|
163
|
-
const pagesScanResult = await scanPages()
|
164
|
-
const tree = await scanTree()
|
165
307
|
|
166
|
-
//
|
167
|
-
|
308
|
+
// Ensure we have pages data
|
309
|
+
if (!currentPagesData) {
|
310
|
+
currentPagesData = await scanPages()
|
311
|
+
reportDiagnostics(currentPagesData.diagnostics)
|
312
|
+
}
|
168
313
|
|
169
|
-
//
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
314
|
+
// Generate the module code
|
315
|
+
return {
|
316
|
+
code: generatePagesModule(currentPagesData),
|
317
|
+
moduleType: 'js',
|
318
|
+
}
|
174
319
|
},
|
175
|
-
}
|
320
|
+
},
|
176
321
|
},
|
177
322
|
]
|
178
323
|
}
|
@@ -1,11 +1,11 @@
|
|
1
1
|
import type { Config } from '#api/config/index'
|
2
|
+
import { reportError } from '#api/server/report-error'
|
2
3
|
import type { Hono } from '#dep/hono/index'
|
3
4
|
import type { Vite } from '#dep/vite/index'
|
5
|
+
import { ResponseInternalServerError } from '#lib/kit-temp'
|
4
6
|
import { debug } from '#singletons/debug'
|
5
7
|
import * as HonoNodeServer from '@hono/node-server'
|
6
|
-
import { Err
|
7
|
-
import cleanStack from 'clean-stack'
|
8
|
-
import { ErrorParser } from 'youch-core'
|
8
|
+
import { Err } from '@wollybeard/kit'
|
9
9
|
|
10
10
|
type App = Hono.Hono
|
11
11
|
|
@@ -28,25 +28,7 @@ export const Serve = (
|
|
28
28
|
if (Err.is(error)) {
|
29
29
|
// ━ Clean Stack Trace
|
30
30
|
server.ssrFixStacktrace(error)
|
31
|
-
|
32
|
-
pathFilter: (path) => {
|
33
|
-
return !path.match(/.*rolldown-vite.*/)
|
34
|
-
},
|
35
|
-
basePath: config.paths.project.rootDir,
|
36
|
-
// pretty: true,
|
37
|
-
})
|
38
|
-
error.stack = stack
|
39
|
-
// ━ Log Error
|
40
|
-
Err.log(error)
|
41
|
-
const parser = new ErrorParser()
|
42
|
-
const parsedError = await parser.parse(error)
|
43
|
-
const snippet = parsedError.frames[0]?.source?.map(line => {
|
44
|
-
return line.lineNumber.toString().padStart(4, ' ') + `: ` + line.chunk
|
45
|
-
}).join(`\n`)
|
46
|
-
if (snippet) {
|
47
|
-
console.log('-----------------------------')
|
48
|
-
console.log(snippet)
|
49
|
-
}
|
31
|
+
reportError(error)
|
50
32
|
return error
|
51
33
|
}
|
52
34
|
throw error
|
@@ -97,10 +79,7 @@ export const Serve = (
|
|
97
79
|
const app = await appPromise
|
98
80
|
if (Err.is(app)) {
|
99
81
|
// Err.log(app)
|
100
|
-
return
|
101
|
-
status: Http.Status.InternalServerError.code,
|
102
|
-
statusText: Http.Status.InternalServerError.description,
|
103
|
-
})
|
82
|
+
return ResponseInternalServerError()
|
104
83
|
}
|
105
84
|
const response = await app.fetch(request, { viteDevServer: server })
|
106
85
|
return response
|
package/src/cli/commands/dev.ts
CHANGED
@@ -8,6 +8,7 @@ import { Err, Path } from '@wollybeard/kit'
|
|
8
8
|
import { z } from 'zod'
|
9
9
|
|
10
10
|
const args = Command.create()
|
11
|
+
.parameter(`--debug -d`, z.boolean().optional())
|
11
12
|
.parameter(
|
12
13
|
`--project -p`,
|
13
14
|
// @ts-expect-error
|
@@ -28,7 +29,14 @@ const args = Command.create()
|
|
28
29
|
|
29
30
|
const dir = ensureOptionalAbsoluteWithCwd(args.project) as string
|
30
31
|
|
31
|
-
const viteUserConfig = await Api.ConfigResolver.fromFile({
|
32
|
+
const viteUserConfig = await Api.ConfigResolver.fromFile({
|
33
|
+
dir,
|
34
|
+
overrides: {
|
35
|
+
advanced: {
|
36
|
+
debug: args.debug,
|
37
|
+
},
|
38
|
+
},
|
39
|
+
})
|
32
40
|
|
33
41
|
const viteDevServer = await Err.tryCatch(() => Vite.createServer(viteUserConfig))
|
34
42
|
|
@@ -2,6 +2,7 @@ import { Arr, Language } from '@wollybeard/kit'
|
|
2
2
|
|
3
3
|
export const enVarName = `DEBUG`
|
4
4
|
|
5
|
+
export const deliminator = `,`
|
5
6
|
export const wildcard = `*`
|
6
7
|
export const enVarEnabledValuesStatic = [`true`, wildcard, `1`]
|
7
8
|
|
@@ -10,29 +11,45 @@ export const calcIsEnabledFromEnv = (
|
|
10
11
|
namespace?: string[],
|
11
12
|
): boolean => {
|
12
13
|
const namespace_ = namespace?.map(_ => _.toLowerCase())
|
13
|
-
|
14
|
+
|
15
|
+
const includeFilters = typeof enVars[enVarName] === `string`
|
14
16
|
? enVars[enVarName]
|
15
17
|
.trim()
|
16
18
|
.toLowerCase()
|
17
|
-
.split(
|
18
|
-
.map(
|
19
|
+
.split(deliminator)
|
20
|
+
.map(patternExpression => {
|
21
|
+
return patternExpression
|
22
|
+
.trim()
|
23
|
+
.split(`:`)
|
24
|
+
.map(_ => _.trim())
|
25
|
+
})
|
19
26
|
: undefined
|
20
27
|
|
21
|
-
if (!
|
28
|
+
if (!includeFilters) return false
|
22
29
|
|
23
|
-
if (
|
30
|
+
if (includeFilters.length === 0) return false
|
24
31
|
|
25
|
-
|
32
|
+
// If any is like * then it means "enable everything"
|
33
|
+
if (
|
34
|
+
includeFilters.some(includeFilter => {
|
35
|
+
if (includeFilter.length === 1 && enVarEnabledValuesStatic.includes(includeFilter[0]!)) return true
|
36
|
+
})
|
37
|
+
) return true
|
26
38
|
|
27
|
-
if (
|
28
|
-
|
29
|
-
}
|
39
|
+
// At this point, if there is no namespace (e.g. root), then we cannot match anything
|
40
|
+
if (!namespace_) return false
|
30
41
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
42
|
+
for (const includeFilter of includeFilters) {
|
43
|
+
if (Arr.getLast(includeFilter) !== wildcard) {
|
44
|
+
return includeFilter.join() === namespace_.join()
|
45
|
+
}
|
46
|
+
|
47
|
+
let i = 0
|
48
|
+
for (const segment of includeFilter) {
|
49
|
+
if (segment === wildcard) return true
|
50
|
+
if (segment !== namespace_[i]) return false
|
51
|
+
i++
|
52
|
+
}
|
36
53
|
}
|
37
54
|
|
38
55
|
Language.never()
|