polen 0.9.0-next.3 → 0.9.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.
Files changed (110) hide show
  1. package/build/api/server/report-error.d.ts +2 -0
  2. package/build/api/server/report-error.d.ts.map +1 -0
  3. package/build/api/server/report-error.js +47 -0
  4. package/build/api/server/report-error.js.map +1 -0
  5. package/build/api/vite/data/navbar.d.ts +9 -0
  6. package/build/api/vite/data/navbar.d.ts.map +1 -0
  7. package/build/api/vite/data/navbar.js +6 -0
  8. package/build/api/vite/data/navbar.js.map +1 -0
  9. package/build/api/vite/plugins/core.d.ts.map +1 -1
  10. package/build/api/vite/plugins/core.js +36 -104
  11. package/build/api/vite/plugins/core.js.map +1 -1
  12. package/build/api/vite/plugins/pages.d.ts +12 -3
  13. package/build/api/vite/plugins/pages.d.ts.map +1 -1
  14. package/build/api/vite/plugins/pages.js +155 -35
  15. package/build/api/vite/plugins/pages.js.map +1 -1
  16. package/build/api/vite/plugins/serve.d.ts.map +1 -1
  17. package/build/api/vite/plugins/serve.js +5 -26
  18. package/build/api/vite/plugins/serve.js.map +1 -1
  19. package/build/cli/commands/dev.js +9 -1
  20. package/build/cli/commands/dev.js.map +1 -1
  21. package/build/lib/debug/environment-variable.d.ts +1 -0
  22. package/build/lib/debug/environment-variable.d.ts.map +1 -1
  23. package/build/lib/debug/environment-variable.js +30 -15
  24. package/build/lib/debug/environment-variable.js.map +1 -1
  25. package/build/lib/extensible-data/extensible-data.d.ts +17 -0
  26. package/build/lib/extensible-data/extensible-data.d.ts.map +1 -0
  27. package/build/lib/extensible-data/extensible-data.js +24 -0
  28. package/build/lib/extensible-data/extensible-data.js.map +1 -0
  29. package/build/lib/extensible-data/index.d.ts +2 -0
  30. package/build/lib/extensible-data/index.d.ts.map +1 -0
  31. package/build/lib/extensible-data/index.js +2 -0
  32. package/build/lib/extensible-data/index.js.map +1 -0
  33. package/build/lib/kit-temp.d.ts +2 -0
  34. package/build/lib/kit-temp.d.ts.map +1 -1
  35. package/build/lib/kit-temp.js +10 -1
  36. package/build/lib/kit-temp.js.map +1 -1
  37. package/build/lib/react-router-loader/react-router-loader.d.ts.map +1 -1
  38. package/build/lib/react-router-loader/react-router-loader.js +0 -1
  39. package/build/lib/react-router-loader/react-router-loader.js.map +1 -1
  40. package/build/lib/vite-plugin-json/index.d.ts +2 -0
  41. package/build/lib/vite-plugin-json/index.d.ts.map +1 -0
  42. package/build/lib/vite-plugin-json/index.js +2 -0
  43. package/build/lib/vite-plugin-json/index.js.map +1 -0
  44. package/build/lib/vite-plugin-json/vite-plugin-json.d.ts +64 -0
  45. package/build/lib/vite-plugin-json/vite-plugin-json.d.ts.map +1 -0
  46. package/build/lib/vite-plugin-json/vite-plugin-json.js +59 -0
  47. package/build/lib/vite-plugin-json/vite-plugin-json.js.map +1 -0
  48. package/build/lib/vite-plugin-reactive-data/index.d.ts +2 -0
  49. package/build/lib/vite-plugin-reactive-data/index.d.ts.map +1 -0
  50. package/build/lib/vite-plugin-reactive-data/index.js +2 -0
  51. package/build/lib/vite-plugin-reactive-data/index.js.map +1 -0
  52. package/build/lib/vite-plugin-reactive-data/vite-plugin-reactive-data.d.ts +39 -0
  53. package/build/lib/vite-plugin-reactive-data/vite-plugin-reactive-data.d.ts.map +1 -0
  54. package/build/lib/vite-plugin-reactive-data/vite-plugin-reactive-data.js +92 -0
  55. package/build/lib/vite-plugin-reactive-data/vite-plugin-reactive-data.js.map +1 -0
  56. package/build/lib/vite-plugins/build-logger.d.ts.map +1 -1
  57. package/build/lib/vite-plugins/build-logger.js +9 -8
  58. package/build/lib/vite-plugins/build-logger.js.map +1 -1
  59. package/build/project-data.d.ts +0 -11
  60. package/build/project-data.d.ts.map +1 -1
  61. package/build/template/components/Link.d.ts.map +1 -1
  62. package/build/template/components/Link.jsx +4 -3
  63. package/build/template/components/Link.jsx.map +1 -1
  64. package/build/template/components/sidebar/Sidebar.d.ts +5 -3
  65. package/build/template/components/sidebar/Sidebar.d.ts.map +1 -1
  66. package/build/template/components/sidebar/Sidebar.jsx +3 -3
  67. package/build/template/components/sidebar/Sidebar.jsx.map +1 -1
  68. package/build/template/routes/changelog.jsx +1 -1
  69. package/build/template/routes/changelog.jsx.map +1 -1
  70. package/build/template/routes/reference.jsx +1 -1
  71. package/build/template/routes/reference.jsx.map +1 -1
  72. package/build/template/routes/root.d.ts.map +1 -1
  73. package/build/template/routes/root.jsx +28 -31
  74. package/build/template/routes/root.jsx.map +1 -1
  75. package/build/template/server/app.js +1 -1
  76. package/build/template/server/app.js.map +1 -1
  77. package/build/template/server/render-page.d.ts.map +1 -1
  78. package/build/template/server/render-page.jsx +4 -1
  79. package/build/template/server/render-page.jsx.map +1 -1
  80. package/build/template/server/ssg/generate.js +1 -1
  81. package/build/template/server/ssg/generate.js.map +1 -1
  82. package/build/template/server/ssg/get-route-paths.js +1 -1
  83. package/build/template/server/ssg/get-route-paths.js.map +1 -1
  84. package/package.json +2 -1
  85. package/src/api/server/report-error.ts +61 -0
  86. package/src/api/vite/data/navbar.ts +15 -0
  87. package/src/api/vite/plugins/core.ts +38 -116
  88. package/src/api/vite/plugins/pages.ts +185 -40
  89. package/src/api/vite/plugins/serve.ts +5 -26
  90. package/src/cli/commands/dev.ts +9 -1
  91. package/src/lib/debug/environment-variable.ts +31 -14
  92. package/src/lib/extensible-data/extensible-data.ts +38 -0
  93. package/src/lib/extensible-data/index.ts +1 -0
  94. package/src/lib/kit-temp.ts +12 -1
  95. package/src/lib/react-router-loader/react-router-loader.ts +0 -1
  96. package/src/lib/vite-plugin-json/index.ts +1 -0
  97. package/src/lib/vite-plugin-json/vite-plugin-json.ts +128 -0
  98. package/src/lib/vite-plugin-reactive-data/index.ts +1 -0
  99. package/src/lib/vite-plugin-reactive-data/vite-plugin-reactive-data.ts +131 -0
  100. package/src/lib/vite-plugins/build-logger.ts +10 -8
  101. package/src/project-data.ts +0 -13
  102. package/src/template/components/Link.tsx +6 -3
  103. package/src/template/components/sidebar/Sidebar.tsx +7 -5
  104. package/src/template/routes/changelog.tsx +1 -1
  105. package/src/template/routes/reference.tsx +1 -1
  106. package/src/template/routes/root.tsx +62 -48
  107. package/src/template/server/app.ts +1 -1
  108. package/src/template/server/render-page.tsx +4 -1
  109. package/src/template/server/ssg/generate.ts +1 -1
  110. package/src/template/server/ssg/get-route-paths.ts +1 -1
@@ -0,0 +1,38 @@
1
+ import { computed, reactive } from '@vue/reactivity'
2
+ import type { ComputedRef, UnwrapRefSimple } from '@vue/reactivity'
3
+
4
+ type Join<$Data> = (chunks: $Data[]) => $Data
5
+ type Create<$Data> = () => $Data
6
+
7
+ interface DataTypeOperations<$Data> {
8
+ join: Join<$Data>
9
+ create: Create<$Data>
10
+ }
11
+
12
+ export const create = <$Data extends object = object>(dataTypeOperations: DataTypeOperations<$Data>) => {
13
+ return new ExtensibleData<$Data>(dataTypeOperations)
14
+ }
15
+
16
+ export class ExtensibleData<$Data extends object = object> {
17
+ public value: ComputedRef<$Data> = computed(() => {
18
+ const namespacedDataItems = Array.from(this.namespacedReactiveData.values())
19
+ const data = this.dataTypeOperations.join(namespacedDataItems as $Data[])
20
+ return data
21
+ })
22
+
23
+ private namespacedReactiveData = reactive(new Map<string, $Data>())
24
+
25
+ private dataTypeOperations: DataTypeOperations<$Data>
26
+
27
+ constructor(dataTypeOperations: DataTypeOperations<$Data>) {
28
+ this.dataTypeOperations = dataTypeOperations
29
+ }
30
+
31
+ get(namespace: string): $Data {
32
+ if (!this.namespacedReactiveData.has(namespace)) {
33
+ const data = this.dataTypeOperations.create()
34
+ this.namespacedReactiveData.set(namespace, data as UnwrapRefSimple<$Data>)
35
+ }
36
+ return this.namespacedReactiveData.get(namespace)! as $Data
37
+ }
38
+ }
@@ -0,0 +1 @@
1
+ export * as ExtensibleData from './extensible-data.ts'
@@ -12,7 +12,7 @@
12
12
  //
13
13
  //
14
14
 
15
- import { Fs, Path, Undefined } from '@wollybeard/kit'
15
+ import { Fs, Http, Path, Undefined } from '@wollybeard/kit'
16
16
  import type { ResolveHookContext } from 'node:module'
17
17
 
18
18
  export const arrayEquals = (a: any[], b: any[]) => {
@@ -95,3 +95,14 @@ export const ObjPartition = <T extends object, K extends keyof T>(
95
95
  picked: {} as Pick<T, K>,
96
96
  })
97
97
  }
98
+
99
+ export const ensureEnd = (string: string, ending: string) => {
100
+ if (string.endsWith(ending)) return string
101
+ return string + ending
102
+ }
103
+
104
+ export const ResponseInternalServerError = () =>
105
+ new Response(null, {
106
+ status: Http.Status.InternalServerError.code,
107
+ statusText: Http.Status.InternalServerError.description,
108
+ })
@@ -12,7 +12,6 @@ export const createLoader = <loader extends Loader>(loader: loader): loader => {
12
12
  const serialized: Serialized = {
13
13
  superjsonData: superjson.stringify(data),
14
14
  }
15
- // console.log({ serialized })
16
15
  return serialized
17
16
  }
18
17
  }
@@ -0,0 +1 @@
1
+ export * as VitePluginJson from './vite-plugin-json.ts'
@@ -0,0 +1,128 @@
1
+ import jsesc from 'jsesc'
2
+ // import { id,or,exclude } from 'rolldown/filter'
3
+ import {} from '@rolldown/pluginutils'
4
+ import type { Plugin } from 'vite'
5
+
6
+ export interface Codec {
7
+ stringify(value: any): string
8
+ parse(text: string): any
9
+ }
10
+
11
+ export interface VitePluginJsonImportsOptions {
12
+ /**
13
+ * Use a custom codec.
14
+ */
15
+ codec?: {
16
+ /**
17
+ * Import path for the custom codec to use in generated code.
18
+ *
19
+ * Must be a package name or use a path alias.
20
+ *
21
+ * Examples:
22
+ * - '@my-org/my-codec' (npm package)
23
+ * - '#utils/codec' (package subpath)
24
+ * - 'my-codec' (npm package)
25
+ * - '~/utils/codec' (if ~ is aliased in vite config)
26
+ */
27
+ importPath: string
28
+ /**
29
+ * Custom codec for validation and runtime parsing
30
+ * The codec.parse() is used at build time to validate the JSON
31
+ * The codec will be imported in the generated code for runtime parsing
32
+ * @default JSON
33
+ */
34
+ validate?: Codec
35
+ /**
36
+ * The export (its name) to import.
37
+ *
38
+ * @default 'default'
39
+ */
40
+ importExport?: string
41
+ }
42
+ filter?: {
43
+ /**
44
+ * Module types to process (the file extension without the dot).
45
+ * @default ['json']
46
+ */
47
+ moduleTypes?: string[]
48
+ /**
49
+ * Picomatch patterns to include
50
+ * @default includes all files with configured extensions
51
+ */
52
+ id?: {
53
+ include?: string | string[]
54
+ /**
55
+ * Picomatch patterns to exclude
56
+ * @default excludes node_modules and files with \0 prefix
57
+ */
58
+ exclude?: string | string[]
59
+ }
60
+ }
61
+ /**
62
+ * Plugin name. Useful to customize if providing a custom codec e.g. `superjson`.
63
+ *
64
+ * @default 'json'
65
+ */
66
+ name?: string
67
+ }
68
+
69
+ export const create = (options: VitePluginJsonImportsOptions = {}): Plugin => {
70
+ const codec = options.codec?.validate ?? JSON
71
+ const codecImportExport = options.codec?.importExport ?? `default`
72
+
73
+ const pluginName = options.name ?? `json-imports`
74
+
75
+ // Always exclude \0 prefixed modules
76
+ // eslint-disable-next-line no-control-regex
77
+ const baseExcludePatterns: (string | RegExp)[] = [/^\0/]
78
+ const moduleTypes = options.filter?.moduleTypes ?? [`json`]
79
+ const isCustomCodec = Boolean(options.codec?.importPath)
80
+
81
+ // Check if we should handle this file based on extension
82
+ const shouldHandle = (id: string) => {
83
+ // Exclude internal modules with \0 prefix
84
+ if (id.startsWith('\0')) return false
85
+
86
+ // Check if it has one of our configured extensions
87
+ return moduleTypes.some(type => id.endsWith(`.${type}`))
88
+ }
89
+
90
+ return {
91
+ name: pluginName,
92
+ enforce: 'pre' as const,
93
+ // Transform files based on extension
94
+ transform(code, id) {
95
+ if (!shouldHandle(id)) return
96
+
97
+ try {
98
+ // Skip validation for superjson since the codec validates the envelope format
99
+ if (options.codec?.validate && !options.codec.importPath?.includes('superjson')) {
100
+ codec.parse(code)
101
+ }
102
+
103
+ if (!isCustomCodec) {
104
+ // For native JSON, directly export as JavaScript object literal
105
+ return `export default ${code}`
106
+ } else {
107
+ // For custom codecs, we need to parse at runtime
108
+ if (!options.codec?.importPath) {
109
+ throw new Error(`codec.importPath is required when using a custom codec`)
110
+ }
111
+
112
+ const importIdentifier = codecImportExport === `default` ? `codec` : codecImportExport
113
+ const importStatement = codecImportExport === `default`
114
+ ? `import ${importIdentifier} from '${options.codec.importPath}'`
115
+ : `import { ${codecImportExport} } from '${options.codec.importPath}'`
116
+
117
+ return `
118
+ ${importStatement}
119
+ const data = ${importIdentifier}.parse('${jsesc(code)}')
120
+ export { data as default }`
121
+ }
122
+ } catch (error) {
123
+ const message = error instanceof Error ? error.message : String(error)
124
+ this.error(`Failed to parse JSON in ${id}: ${message}`)
125
+ }
126
+ },
127
+ }
128
+ }
@@ -0,0 +1 @@
1
+ export * as VitePluginReactiveData from './vite-plugin-reactive-data.ts'
@@ -0,0 +1,131 @@
1
+ import { ensureEnd } from '#lib/kit-temp'
2
+ import { VitePluginJson } from '#lib/vite-plugin-json/index'
3
+ import { superjson } from '#singletons/superjson'
4
+ import { type ComputedRef, effect, isRef } from '@vue/reactivity'
5
+ import { Debug } from '@wollybeard/kit'
6
+ import type { Plugin, ViteDevServer } from 'vite'
7
+
8
+ interface ReactiveDataOptions {
9
+ /**
10
+ * Virtual module ID (e.g., 'virtual:polen/navbar') that this data will be exported from.
11
+ * The appropriate extension will be appended automatically based on moduleType.
12
+ */
13
+ moduleId: string
14
+ /**
15
+ * The reactive data to expose.
16
+ * Can be either:
17
+ * - A Vue computed ref (recommended)
18
+ * - A function that returns reactive data
19
+ * - A reactive value directly
20
+ */
21
+ data: ComputedRef<object | unknown[]> | (() => object | unknown[]) | object | unknown[]
22
+ /** Debounce updates (ms). If not set, uses process.nextTick for batching */
23
+ debounce?: number
24
+ /**
25
+ * JSON codec to use (e.g., superjson)
26
+ * Default: superjson
27
+ * Only used when includeJsonPlugin is true
28
+ */
29
+ codec?: VitePluginJson.Codec
30
+ /**
31
+ * Custom plugin name. Can use to help identify this plugin in logs if using many instances of this plugin.
32
+ @default 'reactive-data'
33
+ */
34
+ name?: string
35
+ /**
36
+ * Module type to return. Default: 'json'
37
+ * Use 'superjson' to avoid conflicts with built-in JSON plugin
38
+ */
39
+ moduleType?: string
40
+ }
41
+
42
+ const debug = Debug.create('vite-plugin-reactive-data')
43
+
44
+ export const create = (options: ReactiveDataOptions): Plugin => {
45
+ const codec = options.codec ?? superjson
46
+ const moduleType = options.moduleType ?? 'json'
47
+ const moduleId = ensureEnd(options.moduleId, `.${moduleType}`)
48
+ const name = options.name ?? `reactive-data`
49
+
50
+ let server: ViteDevServer
51
+ let updateTimer: NodeJS.Timeout | undefined
52
+ let updateScheduled = false
53
+
54
+ const doUpdate = () => {
55
+ debug('update')
56
+ updateTimer = undefined
57
+ updateScheduled = false
58
+ if (!server) return
59
+ const moduleNode = server.moduleGraph.getModuleById(moduleId)
60
+ if (moduleNode) {
61
+ server.moduleGraph.invalidateModule(moduleNode)
62
+ }
63
+ }
64
+
65
+ const scheduleUpdate = () => {
66
+ if (options.debounce) {
67
+ // User wants actual debouncing for rapid updates
68
+ if (updateTimer) clearTimeout(updateTimer)
69
+ updateTimer = setTimeout(doUpdate, options.debounce)
70
+ } else {
71
+ // Just batch synchronous updates using nextTick
72
+ if (updateScheduled) return
73
+ updateScheduled = true
74
+ process.nextTick(doUpdate)
75
+ }
76
+ }
77
+
78
+ // Helper to get the current data value
79
+ const getData = () => {
80
+ if (isRef(options.data)) {
81
+ return options.data.value
82
+ } else if (typeof options.data === 'function') {
83
+ return options.data()
84
+ } else {
85
+ return options.data
86
+ }
87
+ }
88
+
89
+ // Set up reactive effect immediately
90
+ effect(() => {
91
+ // Access data to track dependencies
92
+ const data = getData()
93
+ debug('data changed:', data)
94
+ // Trigger update only if server is available
95
+ if (server) {
96
+ scheduleUpdate()
97
+ }
98
+ })
99
+
100
+ return {
101
+ name,
102
+
103
+ configureServer(_server) {
104
+ server = _server
105
+ // Trigger initial update since server is now available
106
+ scheduleUpdate()
107
+ },
108
+
109
+ resolveId(id) {
110
+ if (id === moduleId) {
111
+ return moduleId
112
+ }
113
+ },
114
+
115
+ load: {
116
+ // todo: doesn't work for some reason, prefer over handler
117
+ // filter: {
118
+ // id: {
119
+ // include: moduleId,
120
+ // },
121
+ // },
122
+ handler: (id) => {
123
+ if (id !== moduleId) return
124
+
125
+ const data = getData()
126
+ // Return just the raw JSON string - let the JSON plugin handle the transformation
127
+ return codec.stringify(data)
128
+ },
129
+ },
130
+ }
131
+ }
@@ -1,31 +1,33 @@
1
1
  import type { Plugin } from 'vite'
2
2
 
3
+ const log = console.log
4
+
3
5
  export const BuildLogger: Plugin = {
4
6
  // https://rollupjs.org/plugin-development/#build-hooks
5
7
  name: `build-logger`,
6
8
  buildStart(...args) {
7
- console.log(`buildStart`, args)
9
+ log(`buildStart`, args)
8
10
  },
9
11
  resolveId(...args) {
10
- console.log(`resolveId`, args)
12
+ log(`resolveId`, args)
11
13
  },
12
14
  load(...args) {
13
- console.log(`load`, JSON.stringify(args))
15
+ log(`load`, JSON.stringify(args))
14
16
  },
15
17
  shouldTransformCachedModule(...args) {
16
- console.log(`shouldTransformCachedModule`, args)
18
+ log(`shouldTransformCachedModule`, args)
17
19
  },
18
20
  transform(...args) {
19
- console.log(`transform`, args)
21
+ log(`transform`, args)
20
22
  return args[0]
21
23
  },
22
24
  moduleParsed(...args) {
23
- console.log(`\nmoduleParsed`, args)
25
+ log(`\nmoduleParsed`, args)
24
26
  },
25
27
  resolveDynamicImport(...args) {
26
- console.log(`resolveDynamicImport`, args)
28
+ log(`resolveDynamicImport`, args)
27
29
  },
28
30
  buildEnd(...args) {
29
- console.log(`buildEnd`, args)
31
+ log(`buildEnd`, args)
30
32
  },
31
33
  }
@@ -1,14 +1,10 @@
1
1
  import type { Config } from '#api/config/index'
2
- import type { FileRouter } from '#lib/file-router/index'
3
2
  import type { Schema } from './api/schema/index.ts'
4
3
 
5
4
  export interface ProjectData {
6
5
  schema: null | Schema.Schema
7
- siteNavigationItems: SiteNavigationItem[]
8
- sidebarIndex: SidebarIndex
9
6
  faviconPath: string
10
7
  paths: Config.Config[`paths`][`project`]
11
- pagesScanResult: FileRouter.ScanResult
12
8
  server: {
13
9
  static: {
14
10
  directory: string
@@ -16,12 +12,3 @@ export interface ProjectData {
16
12
  }
17
13
  }
18
14
  }
19
-
20
- export interface SiteNavigationItem {
21
- title: string
22
- pathExp: string
23
- }
24
-
25
- export interface SidebarIndex {
26
- [pathExpression: string]: FileRouter.Sidebar.Sidebar
27
- }
@@ -49,11 +49,14 @@ export const getPathActiveReport = (
49
49
  pathExp: string,
50
50
  currentPathExp: string,
51
51
  ): PathActiveReport => {
52
- // Normalize paths for comparison - remove leading slash if present
52
+ // Normalize both paths for comparison
53
+ const normalizedPath = pathExp.startsWith('/') ? pathExp.slice(1) : pathExp
53
54
  const normalizedCurrentPath = currentPathExp.startsWith('/') ? currentPathExp.slice(1) : currentPathExp
54
- const isDirect = normalizedCurrentPath === pathExp
55
- const isdescendant = normalizedCurrentPath.startsWith(pathExp)
55
+
56
+ const isDirect = normalizedCurrentPath === normalizedPath
57
+ const isdescendant = normalizedCurrentPath.startsWith(normalizedPath + '/') && normalizedCurrentPath !== normalizedPath
56
58
  const is = isDirect || isdescendant
59
+
57
60
  return {
58
61
  is,
59
62
  isDirect,
@@ -1,17 +1,19 @@
1
1
  import type { FileRouter } from '#lib/file-router/index'
2
2
  import { Box } from '@radix-ui/themes'
3
+ import type { BoxOwnProps, LayoutProps, MarginProps } from '@radix-ui/themes/props'
3
4
  import { Items } from './SidebarItem.tsx'
4
5
 
5
- interface SidebarProps {
6
- items: FileRouter.Sidebar.Item[]
6
+ interface SidebarProps extends LayoutProps, MarginProps, BoxOwnProps {
7
+ data: FileRouter.Sidebar.Item[]
8
+ style?: React.CSSProperties
7
9
  }
8
10
 
9
- export const Sidebar = ({ items }: SidebarProps) => {
11
+ export const Sidebar = ({ data, ...props }: SidebarProps) => {
10
12
  return (
11
13
  <Box
12
14
  data-testid='sidebar'
13
15
  role='Sidebar'
14
- flexShrink='0'
16
+ {...props}
15
17
  >
16
18
  <style>
17
19
  {`
@@ -20,7 +22,7 @@ export const Sidebar = ({ items }: SidebarProps) => {
20
22
  }
21
23
  `}
22
24
  </style>
23
- <Items items={items} />
25
+ <Items items={data} />
24
26
  </Box>
25
27
  )
26
28
  }
@@ -1,6 +1,6 @@
1
1
  import { createRoute } from '#lib/react-router-aid/react-router-aid'
2
2
  import { createLoader, useLoaderData } from '#lib/react-router-loader/react-router-loader'
3
- import { PROJECT_DATA } from 'virtual:polen/project/data'
3
+ import PROJECT_DATA from 'virtual:polen/project/data.jsonsuper'
4
4
  import { Changelog } from '../components/Changelog.jsx'
5
5
 
6
6
  const loader = createLoader(() => {
@@ -2,7 +2,7 @@ import { createRoute } from '#lib/react-router-aid/react-router-aid'
2
2
  import { createLoader, useLoaderData } from '#lib/react-router-loader/react-router-loader'
3
3
  import { Container, Flex } from '@radix-ui/themes'
4
4
  import { Outlet } from 'react-router'
5
- import { PROJECT_DATA } from 'virtual:polen/project/data'
5
+ import PROJECT_DATA from 'virtual:polen/project/data.jsonsuper'
6
6
  import { MissingSchema } from '../components/MissingSchema.jsx'
7
7
  import { TypeIndex } from '../components/TypeIndex.jsx'
8
8
  import { reference$type } from './reference.$type.jsx'
@@ -1,13 +1,15 @@
1
1
  import type { ReactRouter } from '#dep/react-router/index'
2
2
  import { createRoute } from '#lib/react-router-aid/react-router-aid'
3
3
  import { GitHubLogoIcon } from '@radix-ui/react-icons'
4
- import { Box, Button, Heading, Text } from '@radix-ui/themes'
4
+ import { Box, Button, Grid, Heading, Text } from '@radix-ui/themes'
5
5
  import { Flex, Theme } from '@radix-ui/themes'
6
6
  import radixStylesUrl from '@radix-ui/themes/styles.css?url'
7
7
  import { Arr } from '@wollybeard/kit'
8
8
  import { Link as LinkReactRouter } from 'react-router'
9
9
  import { Outlet, ScrollRestoration, useLocation } from 'react-router'
10
- import { PROJECT_DATA } from 'virtual:polen/project/data'
10
+ import PROJECT_DATA from 'virtual:polen/project/data.jsonsuper'
11
+ import projectDataNavbar from 'virtual:polen/project/data/navbar.jsonsuper'
12
+ import projectDataPages from 'virtual:polen/project/data/pages.jsonsuper'
11
13
  import { pages } from 'virtual:polen/project/pages.jsx'
12
14
  import { templateVariables } from 'virtual:polen/template/variables'
13
15
  import { Link } from '../components/Link.jsx'
@@ -72,54 +74,66 @@ const Layout = () => {
72
74
  }
73
75
 
74
76
  const currentNavPathExp = getCurrentNavPathExp()
75
- const sidebar = currentNavPathExp && PROJECT_DATA.sidebarIndex[currentNavPathExp]
76
- const showSidebar = sidebar && sidebar.items.length > 0
77
+ const sidebar = currentNavPathExp && projectDataPages.sidebarIndex[currentNavPathExp]
78
+ const isShowSidebar = sidebar && sidebar.items.length > 0
79
+
80
+ const header = (
81
+ <Flex
82
+ gridArea={'header'}
83
+ align='center'
84
+ gap='8'
85
+ pb='4'
86
+ mb='8'
87
+ style={{
88
+ borderBottom: `1px solid var(--gray-3)`,
89
+ }}
90
+ >
91
+ <LinkReactRouter
92
+ to='/'
93
+ style={{ color: `inherit`, textDecoration: `none` }}
94
+ >
95
+ <Flex align='center' gap='2'>
96
+ <GitHubLogoIcon style={{ width: 30, height: 30 }} />
97
+ <Text size='3' weight='medium'>
98
+ {templateVariables.title}
99
+ </Text>
100
+ </Flex>
101
+ </LinkReactRouter>
102
+ <Flex direction='row' gap='4'>
103
+ {projectDataNavbar.map((item, key) => (
104
+ <Link key={key} color='gray' to={item.pathExp}>
105
+ {item.title}
106
+ </Link>
107
+ ))}
108
+ </Flex>
109
+ </Flex>
110
+ )
111
+
77
112
  return (
78
113
  <Theme asChild>
79
- <Box m='8'>
80
- <Flex
81
- align='center'
82
- gap='8'
83
- pb='4'
84
- mb='8'
85
- style={{
86
- borderBottom: `1px solid var(--gray-3)`,
87
- }}
88
- >
89
- <LinkReactRouter
90
- to='/'
91
- style={{ color: `inherit`, textDecoration: `none` }}
92
- >
93
- <Flex align='center' gap='2'>
94
- <GitHubLogoIcon style={{ width: 30, height: 30 }} />
95
- <Text size='3' weight='medium'>
96
- {templateVariables.title}
97
- </Text>
98
- </Flex>
99
- </LinkReactRouter>
100
- <Flex direction='row' gap='4'>
101
- {PROJECT_DATA.siteNavigationItems.map((item, key) => (
102
- <Link key={key} color='gray' to={item.pathExp}>
103
- {item.title}
104
- </Link>
105
- ))}
106
- </Flex>
107
- </Flex>
108
- {showSidebar
109
- ? (
110
- <Flex gap='8'>
111
- <Sidebar items={sidebar.items} />
112
- <Box style={{ flex: 1 }}>
113
- <Outlet />
114
- </Box>
115
- </Flex>
116
- )
117
- : (
118
- <Box>
119
- <Outlet />
120
- </Box>
121
- )}
122
- </Box>
114
+ <Grid
115
+ width={{ initial: 'var(--container-4)' }}
116
+ areas="'header header header header header header header header' 'sidebar sidebar . content content content content content'"
117
+ rows='min-content auto'
118
+ columns='repeat(8, 1fr)'
119
+ gapX='2'
120
+ my='8'
121
+ mx='auto'
122
+ >
123
+ {header}
124
+ {isShowSidebar && (
125
+ <Sidebar
126
+ gridColumn='1 / 3'
127
+ gridRow='2 / auto'
128
+ data={sidebar.items}
129
+ // ml='-100px'
130
+ // style={{ transform: 'translate(calc(-100% - var(--space-8)))' }}
131
+ />
132
+ )}
133
+ <Box gridArea='content / content / auto / 8'>
134
+ <Outlet />
135
+ </Box>
136
+ </Grid>
123
137
  </Theme>
124
138
  )
125
139
  }
@@ -5,7 +5,7 @@ import { AppleTouchIcon } from '#lib/apple-touch-icon/index'
5
5
  import { Favicon } from '#lib/favicon/index'
6
6
  import { serveStatic } from '@hono/node-server/serve-static'
7
7
  import { Fs, Http, Path } from '@wollybeard/kit'
8
- import { PROJECT_DATA } from 'virtual:polen/project/data'
8
+ import PROJECT_DATA from 'virtual:polen/project/data.jsonsuper'
9
9
  import { renderPage } from './render-page.jsx'
10
10
  import { view } from './view.ts'
11
11
 
@@ -1,4 +1,6 @@
1
+ import { reportError } from '#api/server/report-error'
1
2
  import type { ReactRouter } from '#dep/react-router/index'
3
+ import { ResponseInternalServerError } from '#lib/kit-temp'
2
4
  import type { ReactRouterAid } from '#lib/react-router-aid/index'
3
5
  import { Arr } from '@wollybeard/kit'
4
6
  import { StrictMode } from 'react'
@@ -22,7 +24,8 @@ export const renderPage = (
22
24
  </StrictMode>,
23
25
  )
24
26
  } catch (cause) {
25
- throw new Error(`Failed to server side render the HTML`, { cause })
27
+ reportError(new Error(`Failed to server side render the HTML`, { cause }))
28
+ return ResponseInternalServerError()
26
29
  }
27
30
 
28
31
  if (__BUILDING__) {
@@ -2,7 +2,7 @@ import { Hono } from '#dep/hono/index'
2
2
  import type { ReactRouter } from '#dep/react-router/index'
3
3
  import { app } from '#template/server/app'
4
4
  import * as NodeFs from 'node:fs/promises'
5
- import { PROJECT_DATA } from 'virtual:polen/project/data'
5
+ import PROJECT_DATA from 'virtual:polen/project/data.jsonsuper'
6
6
  import { renderPage } from '../render-page.jsx'
7
7
  import { getRoutesPaths } from './get-route-paths.ts'
8
8
 
@@ -2,7 +2,7 @@ import { Grafaid } from '#lib/grafaid/index'
2
2
  import { visit } from 'graphql'
3
3
  // Or your specific import path for this type
4
4
  import { ReactRouterAid } from '#lib/react-router-aid/index'
5
- import { PROJECT_DATA } from 'virtual:polen/project/data'
5
+ import PROJECT_DATA from 'virtual:polen/project/data.jsonsuper'
6
6
  import { routes } from '../../routes.jsx'
7
7
 
8
8
  // todo: Frameworks tend to colocate ssg data loaders with routes to solve the following