polen 0.10.0-next.4 → 0.10.0-next.5
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 +2 -1
- package/build/api/config/load.js +5 -5
- package/build/api/config/load.js.map +1 -1
- package/build/api/config-resolver/resolve.js +2 -2
- package/build/api/config-resolver/resolve.js.map +1 -1
- package/build/api/content/$$.d.ts +5 -0
- package/build/api/content/$$.d.ts.map +1 -0
- package/build/api/content/$$.js +5 -0
- package/build/api/content/$$.js.map +1 -0
- package/build/api/content/$.d.ts +2 -0
- package/build/api/content/$.d.ts.map +1 -0
- package/build/api/content/$.js +2 -0
- package/build/api/content/$.js.map +1 -0
- package/build/api/content/metadata.d.ts +10 -0
- package/build/api/content/metadata.d.ts.map +1 -0
- package/build/api/content/metadata.js +9 -0
- package/build/api/content/metadata.js.map +1 -0
- package/build/api/content/page.d.ts +11 -0
- package/build/api/content/page.d.ts.map +1 -0
- package/build/api/content/page.js +2 -0
- package/build/api/content/page.js.map +1 -0
- package/build/api/content/scan.d.ts +19 -0
- package/build/api/content/scan.d.ts.map +1 -0
- package/build/api/content/scan.js +57 -0
- package/build/api/content/scan.js.map +1 -0
- package/build/{lib/file-router/sidebar/types.d.ts → api/content/sidebar.d.ts} +8 -1
- package/build/api/content/sidebar.d.ts.map +1 -0
- package/build/api/content/sidebar.js +90 -0
- package/build/api/content/sidebar.js.map +1 -0
- package/build/api/schema/data-sources/schema-directory/schema-directory.js +1 -1
- package/build/api/schema/data-sources/schema-directory/schema-directory.js.map +1 -1
- package/build/api/vite/plugins/branding/index.js +4 -4
- package/build/api/vite/plugins/branding/index.js.map +1 -1
- package/build/api/vite/plugins/core.js +4 -4
- package/build/api/vite/plugins/core.js.map +1 -1
- package/build/api/vite/plugins/pages.d.ts +6 -8
- package/build/api/vite/plugins/pages.d.ts.map +1 -1
- package/build/api/vite/plugins/pages.js +99 -155
- package/build/api/vite/plugins/pages.js.map +1 -1
- package/build/api/vite/plugins/serve.js +5 -5
- package/build/api/vite/plugins/serve.js.map +1 -1
- package/build/cli/_/self-contained-mode.js +5 -5
- package/build/cli/_/self-contained-mode.js.map +1 -1
- package/build/exports/components.d.ts +2 -0
- package/build/exports/components.d.ts.map +1 -0
- package/build/exports/components.js +2 -0
- package/build/exports/components.js.map +1 -0
- package/build/lib/demos/config-schema.d.ts +14 -14
- package/build/lib/file-router/file-router.d.ts +0 -2
- package/build/lib/file-router/file-router.d.ts.map +1 -1
- package/build/lib/file-router/file-router.js +0 -2
- package/build/lib/file-router/file-router.js.map +1 -1
- package/build/lib/file-router/route.d.ts +2 -0
- package/build/lib/file-router/route.d.ts.map +1 -1
- package/build/lib/file-router/route.js.map +1 -1
- package/build/lib/file-router/scan.d.ts.map +1 -1
- package/build/lib/file-router/scan.js +16 -12
- package/build/lib/file-router/scan.js.map +1 -1
- package/build/singletons/debug.d.ts +1 -1
- package/build/singletons/debug.d.ts.map +1 -1
- package/build/singletons/debug.js +1 -1
- package/build/singletons/debug.js.map +1 -1
- package/build/template/components/content/$$.d.ts +2 -0
- package/build/template/components/content/$$.d.ts.map +1 -0
- package/build/template/components/content/$$.js +2 -0
- package/build/template/components/content/$$.js.map +1 -0
- package/build/template/components/sidebar/Sidebar.d.ts +2 -2
- package/build/template/components/sidebar/Sidebar.d.ts.map +1 -1
- package/build/template/components/sidebar/SidebarItem.d.ts +3 -3
- package/build/template/components/sidebar/SidebarItem.d.ts.map +1 -1
- package/build/template/components/sidebar/SidebarItem.jsx +1 -1
- package/build/template/components/sidebar/SidebarItem.jsx.map +1 -1
- package/package.json +10 -3
- package/src/api/config/load.ts +5 -5
- package/src/api/config-resolver/resolve.ts +2 -2
- package/src/api/content/$$.ts +4 -0
- package/src/api/content/$.test.ts +72 -0
- package/src/api/content/$.ts +1 -0
- package/src/api/content/metadata.ts +11 -0
- package/src/api/content/page.ts +12 -0
- package/src/api/content/scan.ts +82 -0
- package/src/api/content/sidebar.ts +136 -0
- package/src/api/schema/data-sources/schema-directory/schema-directory.ts +1 -1
- package/src/api/vite/plugins/branding/index.ts +4 -4
- package/src/api/vite/plugins/core.ts +4 -4
- package/src/api/vite/plugins/pages.ts +117 -171
- package/src/api/vite/plugins/serve.ts +5 -5
- package/src/cli/_/self-contained-mode.ts +5 -5
- package/src/exports/components.ts +1 -0
- package/src/lib/deployment/$$.ts +1 -1
- package/src/lib/deployment/$.test.ts +3 -3
- package/src/lib/deployment/$.ts +1 -1
- package/src/lib/file-router/file-router.ts +0 -2
- package/src/lib/file-router/linter.test.ts +2 -0
- package/src/lib/file-router/route.ts +2 -0
- package/src/lib/file-router/scan.ts +19 -13
- package/src/lib/task/$.test.ts +3 -3
- package/src/singletons/debug.ts +1 -1
- package/src/template/components/content/$$.ts +1 -0
- package/src/template/components/sidebar/Sidebar.tsx +2 -2
- package/src/template/components/sidebar/SidebarItem.tsx +8 -8
- package/build/lib/file-router/scan-tree.d.ts +0 -20
- package/build/lib/file-router/scan-tree.d.ts.map +0 -1
- package/build/lib/file-router/scan-tree.js +0 -158
- package/build/lib/file-router/scan-tree.js.map +0 -1
- package/build/lib/file-router/sidebar/index.d.ts +0 -3
- package/build/lib/file-router/sidebar/index.d.ts.map +0 -1
- package/build/lib/file-router/sidebar/index.js +0 -4
- package/build/lib/file-router/sidebar/index.js.map +0 -1
- package/build/lib/file-router/sidebar/sidebar-tree.d.ts +0 -9
- package/build/lib/file-router/sidebar/sidebar-tree.d.ts.map +0 -1
- package/build/lib/file-router/sidebar/sidebar-tree.js +0 -85
- package/build/lib/file-router/sidebar/sidebar-tree.js.map +0 -1
- package/build/lib/file-router/sidebar/types.d.ts.map +0 -1
- package/build/lib/file-router/sidebar/types.js +0 -2
- package/build/lib/file-router/sidebar/types.js.map +0 -1
- package/build/lib/tree/index.d.ts +0 -3
- package/build/lib/tree/index.d.ts.map +0 -1
- package/build/lib/tree/index.js +0 -2
- package/build/lib/tree/index.js.map +0 -1
- package/build/lib/tree/tree.d.ts +0 -62
- package/build/lib/tree/tree.d.ts.map +0 -1
- package/build/lib/tree/tree.js +0 -134
- package/build/lib/tree/tree.js.map +0 -1
- package/src/lib/file-router/scan-tree.test.ts +0 -189
- package/src/lib/file-router/scan-tree.ts +0 -205
- package/src/lib/file-router/sidebar/index.ts +0 -3
- package/src/lib/file-router/sidebar/sidebar-tree.test.ts +0 -123
- package/src/lib/file-router/sidebar/sidebar-tree.ts +0 -110
- package/src/lib/file-router/sidebar/types.ts +0 -19
- package/src/lib/tree/index.ts +0 -2
- package/src/lib/tree/tree.test.ts +0 -117
- package/src/lib/tree/tree.ts +0 -183
@@ -1,7 +1,7 @@
|
|
1
1
|
import { Grafaid } from '#lib/grafaid/index'
|
2
2
|
import { GraphqlChange } from '#lib/graphql-change/index'
|
3
3
|
import type { GraphqlChangeset } from '#lib/graphql-changeset/index'
|
4
|
-
import {
|
4
|
+
import { debugPolen } from '#singletons/debug'
|
5
5
|
import { Arr, Path } from '@wollybeard/kit'
|
6
6
|
import { glob } from 'tinyglobby'
|
7
7
|
import type { Schema } from '../../schema.ts'
|
@@ -2,7 +2,7 @@ import type { Config } from '#api/api'
|
|
2
2
|
import { polenVirtual } from '#api/vite/vi'
|
3
3
|
import type { Vite } from '#dep/vite/index'
|
4
4
|
import { type ExistenceDiff, getMutationType, MutationType } from '#lib/mutation-type'
|
5
|
-
import {
|
5
|
+
import { debugPolen } from '#singletons/debug'
|
6
6
|
import { Fs } from '@wollybeard/kit'
|
7
7
|
import type { Plugin } from 'vite'
|
8
8
|
|
@@ -15,8 +15,8 @@ const generateDefaultLogo = async () => {
|
|
15
15
|
}
|
16
16
|
|
17
17
|
export function Branding(config: Config.Config): Plugin {
|
18
|
-
const
|
19
|
-
|
18
|
+
const debug = debugPolen.sub('vite-plugin:branding')
|
19
|
+
debug('initialized')
|
20
20
|
|
21
21
|
return {
|
22
22
|
name: 'polen:branding',
|
@@ -32,7 +32,7 @@ export function Branding(config: Config.Config): Plugin {
|
|
32
32
|
changedFile: file,
|
33
33
|
moduleId: viLogo.resolved,
|
34
34
|
server,
|
35
|
-
debug:
|
35
|
+
debug: debug,
|
36
36
|
})
|
37
37
|
},
|
38
38
|
|
@@ -6,7 +6,7 @@ import type { Vite } from '#dep/vite/index'
|
|
6
6
|
import { VitePluginJson } from '#lib/vite-plugin-json/index'
|
7
7
|
import { VitePluginReactiveData } from '#lib/vite-plugin-reactive-data/index'
|
8
8
|
import { ViteVirtual } from '#lib/vite-virtual/index'
|
9
|
-
import {
|
9
|
+
import { debugPolen } from '#singletons/debug'
|
10
10
|
import { superjson } from '#singletons/superjson'
|
11
11
|
import { Json, Str } from '@wollybeard/kit'
|
12
12
|
import type { ProjectData } from '../../../project-data.ts'
|
@@ -16,7 +16,7 @@ import { createLogger } from '../logger.ts'
|
|
16
16
|
import { polenVirtual } from '../vi.ts'
|
17
17
|
import { Pages } from './pages.ts'
|
18
18
|
|
19
|
-
const
|
19
|
+
const debug = debugPolen.sub(`vite-plugin-core`)
|
20
20
|
|
21
21
|
const viTemplateVariables = polenVirtual([`template`, `variables`])
|
22
22
|
const viTemplateSchemaAugmentations = polenVirtual([`template`, `schema-augmentations`])
|
@@ -87,7 +87,7 @@ export const Core = (config: Config.Config): Vite.PluginOption[] => {
|
|
87
87
|
name: `polen:internal-import-alias`,
|
88
88
|
enforce: 'pre' as const,
|
89
89
|
resolveId(id, importer) {
|
90
|
-
const d =
|
90
|
+
const d = debugPolen.sub(`vite-plugin:internal-import-alias`)
|
91
91
|
|
92
92
|
const isPolenImporter = Boolean(
|
93
93
|
importer
|
@@ -183,7 +183,7 @@ export const Core = (config: Config.Config): Vite.PluginOption[] => {
|
|
183
183
|
{
|
184
184
|
identifier: viProjectData,
|
185
185
|
async loader() {
|
186
|
-
|
186
|
+
debug(`loadingViProjectDataVirtualModule`)
|
187
187
|
const schema = await readSchema()
|
188
188
|
|
189
189
|
// ━ Schema presence causes adding some navbar items
|
@@ -1,36 +1,37 @@
|
|
1
1
|
import type { Config } from '#api/config/index'
|
2
|
+
import { Content } from '#api/content/$'
|
2
3
|
import type { NavbarDataRegistry } from '#api/vite/data/navbar'
|
3
4
|
import { polenVirtual } from '#api/vite/vi'
|
4
5
|
import type { Vite } from '#dep/vite/index'
|
5
6
|
import { reportDiagnostics } from '#lib/file-router/diagnostic-reporter'
|
6
7
|
import { FileRouter } from '#lib/file-router/index'
|
7
|
-
import {
|
8
|
-
import { debug } from '#singletons/debug'
|
8
|
+
import { debugPolen } from '#singletons/debug'
|
9
9
|
import { superjson } from '#singletons/superjson'
|
10
10
|
import mdx from '@mdx-js/rollup'
|
11
11
|
import rehypeShiki from '@shikijs/rehype'
|
12
|
-
import {
|
12
|
+
import { Tree } from '@wollybeard/kit'
|
13
|
+
import { Arr, Cache, Path, Str } from '@wollybeard/kit'
|
14
|
+
import remarkFrontmatter from 'remark-frontmatter'
|
13
15
|
import remarkGfm from 'remark-gfm'
|
14
16
|
|
15
|
-
const
|
17
|
+
const debug = debugPolen.sub(`vite-plugin-pages`)
|
16
18
|
|
17
19
|
export const viProjectPages = polenVirtual([`project`, `pages.jsx`], { allowPluginProcessing: true })
|
18
20
|
export const viProjectPagesData = polenVirtual([`project`, `data`, 'pages.jsonsuper'], { allowPluginProcessing: true })
|
19
21
|
|
20
|
-
export interface
|
22
|
+
export interface Options {
|
21
23
|
config: Config.Config
|
22
24
|
navbarData?: NavbarDataRegistry
|
23
|
-
|
24
|
-
onTreeChange?: (tree: FileRouter.RouteTreeNode) => void
|
25
|
+
onChange?: (scanResult: Content.ScanResult) => void
|
25
26
|
}
|
26
27
|
|
27
28
|
export interface ProjectDataPages {
|
28
29
|
sidebarIndex: SidebarIndex
|
29
|
-
|
30
|
+
pages: Content.Page[]
|
30
31
|
}
|
31
32
|
|
32
33
|
export interface SidebarIndex {
|
33
|
-
[pathExpression: string]:
|
34
|
+
[pathExpression: string]: Content.Sidebar
|
34
35
|
}
|
35
36
|
|
36
37
|
/**
|
@@ -39,58 +40,22 @@ export interface SidebarIndex {
|
|
39
40
|
export const Pages = ({
|
40
41
|
config,
|
41
42
|
navbarData,
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
// Helper functions
|
53
|
-
const scanPages = async () => {
|
54
|
-
if (!pagesCache) {
|
55
|
-
_debug(`Scanning pages - cache is null, loading fresh data`)
|
56
|
-
pagesCache = await FileRouter.scan({
|
57
|
-
dir: config.paths.project.absolute.pages,
|
58
|
-
glob: `**/*.{md,mdx}`,
|
59
|
-
})
|
60
|
-
_debug(`Found ${String(pagesCache.routes.length)} pages`)
|
61
|
-
} else {
|
62
|
-
_debug(`Using cached pages`)
|
63
|
-
}
|
64
|
-
return pagesCache
|
65
|
-
}
|
66
|
-
|
67
|
-
const scanTree = async () => {
|
68
|
-
if (!treeCache) {
|
69
|
-
_debug(`Scanning tree - cache is null, loading fresh data`)
|
70
|
-
const result = await FileRouter.scanTree({
|
71
|
-
dir: config.paths.project.absolute.pages,
|
72
|
-
glob: `**/*.{md,mdx}`,
|
73
|
-
})
|
74
|
-
treeCache = result.routeTree
|
75
|
-
_debug(`Built route tree`)
|
76
|
-
} else {
|
77
|
-
_debug(`Using cached tree`)
|
78
|
-
}
|
79
|
-
return treeCache
|
80
|
-
}
|
81
|
-
|
82
|
-
const clearCache = () => {
|
83
|
-
_debug(`Clearing pages and tree cache`)
|
84
|
-
pagesCache = null
|
85
|
-
treeCache = null
|
86
|
-
}
|
43
|
+
onChange,
|
44
|
+
}: Options): Vite.Plugin[] => {
|
45
|
+
const scanPages = Cache.memoize(debug.trace(async function scanPages() {
|
46
|
+
const result = await Content.scan({
|
47
|
+
dir: config.paths.project.absolute.pages,
|
48
|
+
glob: `**/*.{md,mdx}`,
|
49
|
+
})
|
50
|
+
return result
|
51
|
+
}))
|
87
52
|
|
88
53
|
const isPageFile = (file: string) => {
|
89
54
|
return (file.endsWith(`.md`) || file.endsWith(`.mdx`))
|
90
55
|
&& file.includes(config.paths.project.absolute.pages)
|
91
56
|
}
|
92
57
|
|
93
|
-
const generatePagesModule = (
|
58
|
+
const generatePagesModule = (pages: Content.Page[]): string => {
|
94
59
|
const $ = {
|
95
60
|
pages: `pages`,
|
96
61
|
}
|
@@ -99,17 +64,21 @@ export const Pages = ({
|
|
99
64
|
s`export const ${$.pages} = []`
|
100
65
|
|
101
66
|
// Generate imports and route objects
|
102
|
-
for (const route of
|
67
|
+
for (const { route, metadata } of pages) {
|
103
68
|
const filePathExp = Path.format(route.file.path.absolute)
|
104
69
|
const pathExp = FileRouter.routeToPathExpression(route)
|
105
|
-
const
|
70
|
+
const $$ = {
|
71
|
+
...$,
|
72
|
+
Component: Str.Case.camel(`page ` + Str.titlizeSlug(pathExp)),
|
73
|
+
}
|
106
74
|
|
107
75
|
s`
|
108
|
-
import ${
|
76
|
+
import ${$$.Component} from '${filePathExp}'
|
109
77
|
|
110
|
-
${
|
78
|
+
${$$.pages}.push({
|
111
79
|
path: '${pathExp}',
|
112
|
-
Component: ${
|
80
|
+
Component: ${$$.Component},
|
81
|
+
metadata: ${JSON.stringify(metadata)}
|
113
82
|
})
|
114
83
|
`
|
115
84
|
}
|
@@ -123,7 +92,11 @@ export const Pages = ({
|
|
123
92
|
enforce: `pre` as const,
|
124
93
|
...mdx({
|
125
94
|
jsxImportSource: `polen/react`,
|
126
|
-
remarkPlugins: [
|
95
|
+
remarkPlugins: [
|
96
|
+
// Parse frontmatter blocks so they're removed from content
|
97
|
+
remarkFrontmatter,
|
98
|
+
remarkGfm,
|
99
|
+
],
|
127
100
|
rehypePlugins: [
|
128
101
|
[
|
129
102
|
rehypeShiki,
|
@@ -150,62 +123,58 @@ export const Pages = ({
|
|
150
123
|
// Dev server configuration
|
151
124
|
configureServer(server) {
|
152
125
|
// Add pages directory to watcher
|
153
|
-
|
126
|
+
debug(`configureServer: watch pages directory`, config.paths.project.absolute.pages)
|
154
127
|
server.watcher.add(config.paths.project.absolute.pages)
|
155
128
|
},
|
156
129
|
|
157
130
|
// Hot update handling
|
158
131
|
async handleHotUpdate({ file, server, modules }) {
|
159
|
-
|
132
|
+
debug(`handleHotUpdate`, file)
|
160
133
|
if (!isPageFile(file)) return
|
161
134
|
|
162
|
-
|
135
|
+
debug(`Page file changed:`, file)
|
163
136
|
|
164
|
-
//
|
165
|
-
const oldPages =
|
137
|
+
// Get current pages before clearing cache
|
138
|
+
const oldPages = await scanPages()
|
166
139
|
|
167
140
|
// Clear cache and rescan
|
168
|
-
|
169
|
-
const
|
170
|
-
currentPagesData = newPages
|
141
|
+
scanPages.clear()
|
142
|
+
const newScanResult = await scanPages()
|
171
143
|
|
172
144
|
// Check if page structure changed (added/removed pages)
|
173
|
-
const
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
)
|
178
|
-
|
179
|
-
if (structureChanged) {
|
180
|
-
_debug(`Page structure changed, triggering full reload`)
|
181
|
-
|
182
|
-
// Invalidate virtual module
|
183
|
-
const mod = server.moduleGraph.getModuleById(viProjectPages.id)
|
184
|
-
if (mod) {
|
185
|
-
server.moduleGraph.invalidateModule(mod)
|
186
|
-
_debug(`Invalidated pages virtual module`)
|
187
|
-
}
|
145
|
+
const isJustContentChange = oldPages && !Arr.equalShallowly(
|
146
|
+
oldPages.list.map(p => Path.format(p.route.file.path.absolute)),
|
147
|
+
newScanResult.list.map(p => Path.format(p.route.file.path.absolute)),
|
148
|
+
)
|
188
149
|
|
189
|
-
|
190
|
-
|
191
|
-
reportDiagnostics(newPages.diagnostics)
|
192
|
-
onPagesChange(newPages)
|
193
|
-
}
|
194
|
-
|
195
|
-
if (onTreeChange) {
|
196
|
-
const tree = await scanTree()
|
197
|
-
onTreeChange(tree)
|
198
|
-
currentTreeData = tree
|
199
|
-
}
|
200
|
-
|
201
|
-
// Trigger full reload for structure changes
|
202
|
-
server.ws.send({ type: `full-reload` })
|
203
|
-
return []
|
204
|
-
} else {
|
205
|
-
_debug(`Page content changed, allowing HMR`)
|
150
|
+
if (isJustContentChange) {
|
151
|
+
debug(`Page content changed, allowing HMR`)
|
206
152
|
// Let default HMR handle the MDX file change
|
207
153
|
return modules
|
208
154
|
}
|
155
|
+
|
156
|
+
//
|
157
|
+
// ━━ Manual Invalidation
|
158
|
+
//
|
159
|
+
|
160
|
+
debug(`Page structure changed, triggering full reload`)
|
161
|
+
|
162
|
+
// Invalidate virtual module
|
163
|
+
const mod = server.moduleGraph.getModuleById(viProjectPages.id)
|
164
|
+
if (mod) {
|
165
|
+
server.moduleGraph.invalidateModule(mod)
|
166
|
+
debug(`Invalidated pages virtual module`)
|
167
|
+
}
|
168
|
+
|
169
|
+
// Notify about changes
|
170
|
+
if (onChange) {
|
171
|
+
reportDiagnostics(newScanResult.diagnostics)
|
172
|
+
onChange(newScanResult)
|
173
|
+
}
|
174
|
+
|
175
|
+
// Trigger full reload for structure changes
|
176
|
+
server.ws.send({ type: `full-reload` })
|
177
|
+
return []
|
209
178
|
},
|
210
179
|
resolveId(id) {
|
211
180
|
if (id === viProjectPagesData.id) {
|
@@ -218,25 +187,13 @@ export const Pages = ({
|
|
218
187
|
// },
|
219
188
|
async handler(id) {
|
220
189
|
if (id !== viProjectPagesData.resolved) return
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
glob: `**/*.{md,mdx}`,
|
229
|
-
})
|
230
|
-
// Report any diagnostics from initial scan
|
231
|
-
reportDiagnostics(currentPagesData.diagnostics)
|
232
|
-
}
|
233
|
-
if (!currentTreeData) {
|
234
|
-
_debug(`loadingTreeDataInitially`)
|
235
|
-
currentTreeData = await getRouteTree(config)
|
236
|
-
}
|
237
|
-
const pagesScanResult = currentPagesData
|
238
|
-
const routeTree = currentTreeData
|
239
|
-
_debug(`usingPageRoutesFromPagesPlugin`, pagesScanResult.routes.length)
|
190
|
+
debug(`viProjectDataPages`)
|
191
|
+
|
192
|
+
const scanResult = await scanPages()
|
193
|
+
|
194
|
+
// Report any diagnostics
|
195
|
+
reportDiagnostics(scanResult.diagnostics)
|
196
|
+
debug(`Found ${String(scanResult.list.length)} visible pages`)
|
240
197
|
|
241
198
|
//
|
242
199
|
// ━━ Build Navbar
|
@@ -248,34 +205,26 @@ export const Pages = ({
|
|
248
205
|
navbarPages.length = 0 // Clear existing
|
249
206
|
|
250
207
|
// Process first-level children as navigation items
|
251
|
-
|
252
|
-
|
253
|
-
//
|
254
|
-
const
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
208
|
+
if (scanResult.tree.root) {
|
209
|
+
for (const child of scanResult.tree.root.children) {
|
210
|
+
// Now we have Page objects in the tree
|
211
|
+
const page = child.value
|
212
|
+
const pathExp = FileRouter.routeToPathExpression(page.route)
|
213
|
+
|
214
|
+
// Skip hidden pages and index files at root level
|
215
|
+
if (page.metadata.hidden || page.route.logical.path.slice(-1)[0] === 'index') {
|
216
|
+
continue
|
217
|
+
}
|
218
|
+
|
219
|
+
// Only include top-level pages (files directly in pages directory)
|
220
|
+
if (page.route.logical.path.length === 1) {
|
221
|
+
const title = Str.titlizeSlug(page.route.logical.path[0]!)
|
259
222
|
navbarPages.push({
|
260
223
|
// IMPORTANT: Always ensure paths start with '/' for React Router compatibility.
|
261
|
-
// Without the leading slash, React Router treats paths as relative, which causes
|
262
|
-
// hydration mismatches between SSR (where base path is prepended) and client
|
263
|
-
// (where basename is configured). This ensures consistent behavior.
|
264
224
|
pathExp: pathExp.startsWith('/') ? pathExp : '/' + pathExp,
|
265
225
|
title,
|
266
226
|
})
|
267
227
|
}
|
268
|
-
} else if (child.value.type === 'file' && child.value.name !== 'index') {
|
269
|
-
const pathExp = FileRouter.pathToExpression([child.value.name])
|
270
|
-
const title = Str.titlizeSlug(child.value.name)
|
271
|
-
navbarPages.push({
|
272
|
-
// IMPORTANT: Always ensure paths start with '/' for React Router compatibility.
|
273
|
-
// Without the leading slash, React Router treats paths as relative, which causes
|
274
|
-
// hydration mismatches between SSR (where base path is prepended) and client
|
275
|
-
// (where basename is configured). This ensures consistent behavior.
|
276
|
-
pathExp: pathExp.startsWith('/') ? pathExp : '/' + pathExp,
|
277
|
-
title,
|
278
|
-
})
|
279
228
|
}
|
280
229
|
}
|
281
230
|
}
|
@@ -286,17 +235,25 @@ export const Pages = ({
|
|
286
235
|
|
287
236
|
const sidebarIndex: SidebarIndex = {}
|
288
237
|
|
289
|
-
// Build sidebar for each top-level directory
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
238
|
+
// Build sidebar for each top-level directory using the page tree
|
239
|
+
if (scanResult.tree.root) {
|
240
|
+
Tree.visit(scanResult.tree, (node) => {
|
241
|
+
if (!node.value) return
|
242
|
+
const page = node.value as any
|
243
|
+
// Only process top-level directories (pages with logical path length > 1 indicate nested structure)
|
244
|
+
if (page.route.logical.path.length === 1 && node.children.length > 0) {
|
245
|
+
const topLevelDir = page.route.logical.path[0]!
|
246
|
+
const pathExp = `/${topLevelDir}`
|
247
|
+
|
248
|
+
// Create a subtree for this directory
|
249
|
+
const subtree = Tree.Tree(Tree.Node(page, node.children)) as Tree.Tree<any>
|
250
|
+
|
251
|
+
// Build sidebar using the new page tree builder
|
252
|
+
const sidebar = Content.buildFromPageTree(subtree, [topLevelDir])
|
253
|
+
debug(`Built sidebar for ${pathExp}:`, sidebar)
|
254
|
+
sidebarIndex[pathExp] = sidebar
|
255
|
+
}
|
256
|
+
})
|
300
257
|
}
|
301
258
|
|
302
259
|
//
|
@@ -305,7 +262,7 @@ export const Pages = ({
|
|
305
262
|
|
306
263
|
const projectDataPages: ProjectDataPages = {
|
307
264
|
sidebarIndex,
|
308
|
-
|
265
|
+
pages: scanResult.list,
|
309
266
|
}
|
310
267
|
|
311
268
|
// Return just the JSON string - let the JSON plugin handle the transformation
|
@@ -313,7 +270,7 @@ export const Pages = ({
|
|
313
270
|
},
|
314
271
|
},
|
315
272
|
},
|
316
|
-
// Plugin
|
273
|
+
// Plugin 3: Virtual Module for Pages Routes
|
317
274
|
{
|
318
275
|
name: 'polen:pages:routes',
|
319
276
|
resolveId(id) {
|
@@ -328,17 +285,15 @@ export const Pages = ({
|
|
328
285
|
handler: async (id) => {
|
329
286
|
if (id !== viProjectPages.resolved) return
|
330
287
|
|
331
|
-
|
288
|
+
debug(`Loading viProjectPages virtual module`)
|
332
289
|
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
reportDiagnostics(currentPagesData.diagnostics)
|
337
|
-
}
|
290
|
+
const scanResult = await scanPages()
|
291
|
+
reportDiagnostics(scanResult.diagnostics)
|
292
|
+
const code = generatePagesModule(scanResult.list)
|
338
293
|
|
339
294
|
// Generate the module code
|
340
295
|
return {
|
341
|
-
code
|
296
|
+
code,
|
342
297
|
moduleType: 'js',
|
343
298
|
}
|
344
299
|
},
|
@@ -346,12 +301,3 @@ export const Pages = ({
|
|
346
301
|
},
|
347
302
|
]
|
348
303
|
}
|
349
|
-
|
350
|
-
// Helper to get tree
|
351
|
-
export const getRouteTree = async (config: Config.Config): Promise<FileRouter.RouteTreeNode> => {
|
352
|
-
const result = await FileRouter.scanTree({
|
353
|
-
dir: config.paths.project.absolute.pages,
|
354
|
-
glob: `**/*.{md,mdx}`,
|
355
|
-
})
|
356
|
-
return result.routeTree
|
357
|
-
}
|
@@ -3,7 +3,7 @@ import { reportError } from '#api/server/report-error'
|
|
3
3
|
import type { Hono } from '#dep/hono/index'
|
4
4
|
import type { Vite } from '#dep/vite/index'
|
5
5
|
import { ResponseInternalServerError } from '#lib/kit-temp'
|
6
|
-
import {
|
6
|
+
import { debugPolen } from '#singletons/debug'
|
7
7
|
import * as HonoNodeServer from '@hono/node-server'
|
8
8
|
import { Err } from '@wollybeard/kit'
|
9
9
|
|
@@ -16,11 +16,11 @@ interface AppServerModule {
|
|
16
16
|
export const Serve = (
|
17
17
|
config: Config.Config,
|
18
18
|
): Vite.PluginOption => {
|
19
|
-
const
|
19
|
+
const debug = debugPolen.sub(`serve`)
|
20
20
|
let appPromise: Promise<App | Error>
|
21
21
|
|
22
22
|
const reloadApp = async ({ server }: { server: Vite.ViteDevServer }): Promise<App | Error> => {
|
23
|
-
|
23
|
+
debug('reloadApp')
|
24
24
|
return server.ssrLoadModule(config.paths.framework.template.server.app)
|
25
25
|
.then(module => module as AppServerModule)
|
26
26
|
.then(module => module.app)
|
@@ -55,12 +55,12 @@ export const Serve = (
|
|
55
55
|
}
|
56
56
|
},
|
57
57
|
handleHotUpdate({ server }) {
|
58
|
-
|
58
|
+
debug('handleHotUpdate')
|
59
59
|
// Reload app server immediately in the background
|
60
60
|
appPromise = reloadApp({ server })
|
61
61
|
},
|
62
62
|
async configureServer(server) {
|
63
|
-
|
63
|
+
debug('configureServer')
|
64
64
|
// Initial load
|
65
65
|
appPromise = reloadApp({ server })
|
66
66
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import type { Vite } from '#dep/vite/index'
|
2
2
|
import { type ImportEvent, isSpecifierFromPackage } from '#lib/kit-temp'
|
3
3
|
import { packagePaths } from '#package-paths'
|
4
|
-
import {
|
4
|
+
import { debugPolen } from '#singletons/debug'
|
5
5
|
import type * as Module from 'node:module'
|
6
6
|
import { fileURLToPath } from 'node:url'
|
7
7
|
|
@@ -18,7 +18,7 @@ export function initialize(data: SelfContainedModeHooksData) {
|
|
18
18
|
export const resolve: Module.ResolveHook = async (specifier, context, nextResolve) => {
|
19
19
|
if (!data_) throw new Error(`Self-contained mode not initialized`)
|
20
20
|
|
21
|
-
const
|
21
|
+
const debug = debugPolen.sub(`node-module-hooks`)
|
22
22
|
|
23
23
|
const from: ImportEvent = {
|
24
24
|
specifier,
|
@@ -32,7 +32,7 @@ export const resolve: Module.ResolveHook = async (specifier, context, nextResolv
|
|
32
32
|
importerPathExpOrFileUrlExp: from.context.parentURL,
|
33
33
|
})
|
34
34
|
) {
|
35
|
-
|
35
|
+
debug(`resolve check`, { specifier, context })
|
36
36
|
|
37
37
|
const to: ImportEvent = {
|
38
38
|
specifier: from.specifier,
|
@@ -43,7 +43,7 @@ export const resolve: Module.ResolveHook = async (specifier, context, nextResolv
|
|
43
43
|
},
|
44
44
|
}
|
45
45
|
|
46
|
-
|
46
|
+
debug(`resolve`, { from, to })
|
47
47
|
|
48
48
|
await nextResolve(to.specifier, to.context)
|
49
49
|
}
|
@@ -66,7 +66,7 @@ export const checkIsSelfImportFromProject = (input: {
|
|
66
66
|
}
|
67
67
|
|
68
68
|
export const VitePluginSelfContainedMode = ({ projectDirPathExp }: { projectDirPathExp: string }): Vite.Plugin => {
|
69
|
-
const d =
|
69
|
+
const d = debugPolen.sub(`vite-plugin:self-contained-import`)
|
70
70
|
|
71
71
|
return {
|
72
72
|
name: `polen:self-contained-import`,
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from '#template/components/content/$$'
|
package/src/lib/deployment/$$.ts
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
export * from './metadata.ts'
|
2
|
-
export * from './path-manager.ts'
|
2
|
+
export * from './path-manager.ts'
|
@@ -26,7 +26,7 @@ describe('metadata', () => {
|
|
26
26
|
}
|
27
27
|
|
28
28
|
await Deployment.metadata.write(metadata, testDir)
|
29
|
-
|
29
|
+
|
30
30
|
const result = await Deployment.metadata.read(testDir)
|
31
31
|
expect(result).toEqual(metadata)
|
32
32
|
})
|
@@ -46,8 +46,8 @@ describe('metadata', () => {
|
|
46
46
|
}
|
47
47
|
|
48
48
|
await Deployment.metadata.write(metadata, testDir)
|
49
|
-
|
49
|
+
|
50
50
|
const fileExists = await Fs.exists(`${testDir}/.deployment.json`)
|
51
51
|
expect(fileExists).toBe(true)
|
52
52
|
})
|
53
|
-
})
|
53
|
+
})
|
package/src/lib/deployment/$.ts
CHANGED
@@ -1 +1 @@
|
|
1
|
-
export * as Deployment from './$$.ts'
|
1
|
+
export * as Deployment from './$$.ts'
|
@@ -36,6 +36,8 @@ export const pathToExpression = (path: Path) => {
|
|
36
36
|
export interface Route {
|
37
37
|
logical: RouteLogical
|
38
38
|
file: RouteFile
|
39
|
+
id: string // Absolute file path for unique identification
|
40
|
+
parentId: string | null // Parent directory path, null for root-level files
|
39
41
|
}
|
40
42
|
|
41
43
|
export interface RouteLogical {
|