davaux 0.8.0 → 0.8.1

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 (90) hide show
  1. package/package.json +6 -2
  2. package/BASELINE.md +0 -169
  3. package/CLAUDE.md +0 -518
  4. package/ROADMAP.md +0 -198
  5. package/build.mjs +0 -101
  6. package/client/control.ts +0 -247
  7. package/client/hydrate.ts +0 -37
  8. package/client/index.ts +0 -19
  9. package/client/jsx-runtime.ts +0 -209
  10. package/client/resource.ts +0 -122
  11. package/client/signal.ts +0 -211
  12. package/client/store.ts +0 -110
  13. package/client/useHead.ts +0 -63
  14. package/pka.config.json +0 -32
  15. package/src/build/config.ts +0 -42
  16. package/src/build/index.ts +0 -6
  17. package/src/build/plugins.ts +0 -118
  18. package/src/cli.ts +0 -502
  19. package/src/config.ts +0 -197
  20. package/src/create-multisite.ts +0 -310
  21. package/src/create.ts +0 -194
  22. package/src/dev/blueprints.ts +0 -75
  23. package/src/dev/components.ts +0 -108
  24. package/src/dev/insert.ts +0 -221
  25. package/src/dev/remove.ts +0 -677
  26. package/src/dev/watch.ts +0 -3098
  27. package/src/errors.ts +0 -64
  28. package/src/generate.ts +0 -228
  29. package/src/index.ts +0 -67
  30. package/src/island.ts +0 -47
  31. package/src/jsx-runtime.d.ts +0 -408
  32. package/src/jsx-runtime.d.ts.map +0 -1
  33. package/src/jsx-runtime.ts +0 -536
  34. package/src/link.ts +0 -49
  35. package/src/oml/fragment.ts +0 -54
  36. package/src/oml/index.ts +0 -21
  37. package/src/oml/jsx-runtime.ts +0 -121
  38. package/src/oml/jsx.ts +0 -151
  39. package/src/oml/page.ts +0 -13
  40. package/src/oml/render.ts +0 -181
  41. package/src/oml/types.ts +0 -159
  42. package/src/router/handler.ts +0 -515
  43. package/src/router/matcher.ts +0 -52
  44. package/src/router/scanner.ts +0 -272
  45. package/src/server/index.ts +0 -49
  46. package/src/signal.ts +0 -39
  47. package/src/ssg.ts +0 -253
  48. package/src/test/actions.test.ts +0 -40
  49. package/src/test/body-limits.test.ts +0 -83
  50. package/src/test/errors.test.ts +0 -53
  51. package/src/test/fixtures/routes/[id].page.ts +0 -3
  52. package/src/test/fixtures/routes/_error.ts +0 -6
  53. package/src/test/fixtures/routes/_global.ts +0 -8
  54. package/src/test/fixtures/routes/_layout-template.ts +0 -7
  55. package/src/test/fixtures/routes/_layout.ts +0 -7
  56. package/src/test/fixtures/routes/_layout_scripts.ts +0 -8
  57. package/src/test/fixtures/routes/_middleware.ts +0 -8
  58. package/src/test/fixtures/routes/_redirect301_mw.ts +0 -5
  59. package/src/test/fixtures/routes/_redirect_mw.ts +0 -5
  60. package/src/test/fixtures/routes/about.page.ts +0 -6
  61. package/src/test/fixtures/routes/action.page.ts +0 -11
  62. package/src/test/fixtures/routes/api/form-all.post.ts +0 -5
  63. package/src/test/fixtures/routes/api/form-limited.post.ts +0 -6
  64. package/src/test/fixtures/routes/api/response-obj.get.ts +0 -17
  65. package/src/test/fixtures/routes/api/upload.post.ts +0 -14
  66. package/src/test/fixtures/routes/api/users.get.ts +0 -3
  67. package/src/test/fixtures/routes/api/xml.get.ts +0 -5
  68. package/src/test/fixtures/routes/auth/_middleware.ts +0 -11
  69. package/src/test/fixtures/routes/auth/protected.page.ts +0 -3
  70. package/src/test/fixtures/routes/index.page.ts +0 -3
  71. package/src/test/fixtures/routes/oml.page.ts +0 -7
  72. package/src/test/fixtures/routes/redirect.page.ts +0 -3
  73. package/src/test/fixtures/routes/ssg/[slug].page.ts +0 -8
  74. package/src/test/fixtures/routes/ssg/server.page.ts +0 -5
  75. package/src/test/fixtures/routes/state.page.ts +0 -4
  76. package/src/test/fixtures/routes/throw.page.ts +0 -5
  77. package/src/test/fixtures/routes/wiki/[...slug].page.ts +0 -3
  78. package/src/test/helpers.ts +0 -132
  79. package/src/test/layouts.test.ts +0 -76
  80. package/src/test/middleware.test.ts +0 -69
  81. package/src/test/multipart.test.ts +0 -91
  82. package/src/test/oml-routing.test.ts +0 -59
  83. package/src/test/oml.test.ts +0 -429
  84. package/src/test/redirects.test.ts +0 -32
  85. package/src/test/routing.test.ts +0 -118
  86. package/src/test/ssg.test.ts +0 -273
  87. package/src/test/web-response.test.ts +0 -33
  88. package/src/types.ts +0 -670
  89. package/tsconfig.client.json +0 -17
  90. package/tsconfig.json +0 -20
package/client/useHead.ts DELETED
@@ -1,63 +0,0 @@
1
- import { createEffect, onCleanup } from './signal.js'
2
-
3
- export interface MetaDescriptor {
4
- /** `<meta name="...">` value. Mutually exclusive with `property`. */
5
- name?: string
6
- /** `<meta property="...">` value (Open Graph, etc.). Mutually exclusive with `name`. */
7
- property?: string
8
- content: string | (() => string)
9
- }
10
-
11
- export interface UseHeadOptions {
12
- /** Reactive document title. A function re-runs whenever its signals change. */
13
- title?: string | (() => string)
14
- /** Meta tags to add/update in `<head>`. Existing tags are updated in place. */
15
- meta?: MetaDescriptor[]
16
- }
17
-
18
- /**
19
- * Update `document.title` and `<meta>` tags from inside a client island.
20
- * String values are set once; function values are wrapped in `createEffect`
21
- * and update reactively whenever their signals change.
22
- *
23
- * No-op on the server — use `ctx.head` from the page handler for initial SSR values.
24
- *
25
- * @example
26
- * useHead({
27
- * title: () => `${article()} — My Site`,
28
- * meta: [{ name: 'description', content: () => article().summary }],
29
- * })
30
- */
31
- export function useHead(options: UseHeadOptions): void {
32
- if (typeof document === 'undefined') return
33
-
34
- if (options.title !== undefined) {
35
- const title = options.title
36
- createEffect(() => {
37
- document.title = typeof title === 'function' ? title() : title
38
- })
39
- }
40
-
41
- for (const descriptor of options.meta ?? []) {
42
- const attr = descriptor.name !== undefined ? 'name' : 'property'
43
- const attrValue = (descriptor.name ?? descriptor.property) as string
44
-
45
- let el = document.querySelector(`meta[${attr}="${attrValue}"]`) as HTMLMetaElement | null
46
- const created = !el
47
- if (!el) {
48
- el = document.createElement('meta')
49
- el.setAttribute(attr, attrValue)
50
- document.head.appendChild(el)
51
- }
52
-
53
- const metaEl = el
54
- const content = descriptor.content
55
- createEffect(() => {
56
- metaEl.content = typeof content === 'function' ? content() : content
57
- })
58
-
59
- if (created) {
60
- onCleanup(() => metaEl.remove())
61
- }
62
- }
63
- }
package/pka.config.json DELETED
@@ -1,32 +0,0 @@
1
- {
2
- "configVersion": 2,
3
- "_pkaGenerated": true,
4
- "mode": "claude-code",
5
- "outputDir": "./.pka",
6
- "maxFileSize": 1048576,
7
- "noGit": false,
8
- "noContext": false,
9
- "noConcat": false,
10
- "noFlatten": false,
11
- "install": false,
12
- "noGitignore": false,
13
- "xml": false,
14
- "agentsMd": null,
15
- "copilot": null,
16
- "cursorRules": null,
17
- "hierarchical": false,
18
- "scaffoldCommands": false,
19
- "compact": false,
20
- "compactTokens": 0,
21
- "compactOmit": false,
22
- "compactKeep": [],
23
- "compactPreview": false,
24
- "diff": false,
25
- "force": false,
26
- "watch": false,
27
- "since": null,
28
- "includeExt": [],
29
- "excludeDir": [],
30
- "description": "",
31
- "instructions": ""
32
- }
@@ -1,42 +0,0 @@
1
- import { existsSync } from 'node:fs'
2
- import { mkdir, rm } from 'node:fs/promises'
3
- import { join, resolve } from 'node:path'
4
- import type { DavauxConfig } from '../config.js'
5
-
6
- const CONFIG_FILES = ['davaux.config.ts', 'davaux.config.js', 'davaux.config.mjs']
7
-
8
- // Compile and import the project's davaux.config.* file.
9
- // Returns an empty object if no config file is found.
10
- export async function loadConfig(cwd: string): Promise<DavauxConfig> {
11
- for (const name of CONFIG_FILES) {
12
- const configPath = resolve(cwd, name)
13
- if (!existsSync(configPath)) continue
14
-
15
- // Write to node_modules/.cache/davaux/ so Node.js resolves externals
16
- // (esbuild, davaux, etc.) via the project's own node_modules tree.
17
- const cacheDir = resolve(cwd, 'node_modules', '.cache', 'davaux')
18
- await mkdir(cacheDir, { recursive: true })
19
- const outfile = join(cacheDir, `config-${Date.now()}.mjs`)
20
-
21
- try {
22
- const { build } = await import('esbuild')
23
- await build({
24
- entryPoints: [configPath],
25
- outfile,
26
- format: 'esm',
27
- platform: 'node',
28
- target: 'node22',
29
- bundle: true,
30
- // Keep node built-ins and framework packages as external imports;
31
- // everything else (user plugin deps) is bundled in.
32
- external: ['node:*', 'esbuild', 'davaux', 'davaux/*'],
33
- logLevel: 'silent',
34
- })
35
- const mod = await import(outfile)
36
- return (mod.default ?? {}) as DavauxConfig
37
- } finally {
38
- await rm(outfile, { force: true }).catch(() => {})
39
- }
40
- }
41
- return {}
42
- }
@@ -1,6 +0,0 @@
1
- export {
2
- collectCss,
3
- cssCollectorPlugin,
4
- generateIslandsEntry,
5
- islandServerPlugin,
6
- } from './plugins.js'
@@ -1,118 +0,0 @@
1
- import { mkdir, readdir, readFile, writeFile } from 'node:fs/promises'
2
- import { basename, dirname, join } from 'node:path'
3
- import { type Plugin, transform } from 'esbuild'
4
- import type { IslandFile } from '../types.js'
5
-
6
- // ─── Island server plugin ─────────────────────────────────────────────────────
7
- //
8
- // When the routes bundle imports a file from the islands directory, this plugin
9
- // intercepts at load time and returns a thin server wrapper instead of the raw
10
- // source. The wrapper re-exports the component wrapped with island() so the
11
- // route gets back a function that renders SSR HTML + serialized props.
12
- //
13
- // The actual island source is loaded under the 'island-raw' namespace, which:
14
- // 1. Strips any @jsxImportSource pragma (server context sets its own)
15
- // 2. Allows the route context's jsxImportSource:'davaux' + alias to apply
16
-
17
- export function islandServerPlugin(islandsDirs: string | string[]): Plugin {
18
- const dirs = Array.isArray(islandsDirs) ? islandsDirs : [islandsDirs]
19
- return {
20
- name: 'davaux-island-server',
21
- setup(build) {
22
- // Intercept file-namespace loads of island source files
23
- build.onLoad({ filter: /\.(tsx?|jsx?)$/ }, async (args) => {
24
- if (args.namespace !== 'file') return
25
- if (!dirs.some((d) => args.path.startsWith(d))) return
26
-
27
- const id = basename(args.path).replace(/\.(tsx?|jsx?)$/, '')
28
- return {
29
- contents: [
30
- `import Component from ${JSON.stringify(`${args.path}?island-raw`)};`,
31
- `import { island } from 'davaux/island';`,
32
- `export default island(Component, ${JSON.stringify(id)});`,
33
- ].join('\n'),
34
- loader: 'js',
35
- resolveDir: dirname(args.path),
36
- }
37
- })
38
-
39
- // Resolve the ?island-raw marker → island-raw namespace (bypasses the wrapper)
40
- build.onResolve({ filter: /\?island-raw$/ }, (args) => ({
41
- path: args.path.replace(/\?island-raw$/, ''),
42
- namespace: 'island-raw',
43
- }))
44
-
45
- // Load the raw island source, stripping any file-level @jsxImportSource pragma
46
- // and replacing it with the standard 'davaux' runtime so the island renders to
47
- // HTML strings on the server (OML is only needed at the route/page level).
48
- build.onLoad({ filter: /.*/, namespace: 'island-raw' }, async (args) => {
49
- let source = await readFile(args.path, 'utf8')
50
- source = source.replace(/\/\*\*?\s*@jsxImportSource\s+\S+\s*\*\//g, '')
51
- source = `/** @jsxImportSource davaux */\n${source}`
52
- const ext = (args.path.match(/\.(tsx?|jsx?)$/)?.[1] ?? 'ts') as 'tsx' | 'ts' | 'jsx' | 'js'
53
- return { contents: source, loader: ext, resolveDir: dirname(args.path) }
54
- })
55
- },
56
- }
57
- }
58
-
59
- // ─── CSS collector ────────────────────────────────────────────────────────────
60
- //
61
- // Scans a directory recursively for all *.css files produced by esbuild
62
- // (side-effect CSS imports in routes and islands) and concatenates them into a
63
- // single stylesheet. Returns true if CSS was found and written, false otherwise.
64
-
65
- export async function collectCss(
66
- scanDir: string,
67
- stylesOutFile: string,
68
- minify = false,
69
- ): Promise<boolean> {
70
- const cssFiles: string[] = []
71
- async function walk(dir: string): Promise<void> {
72
- const entries = await readdir(dir, { withFileTypes: true }).catch(() => [])
73
- for (const e of entries) {
74
- const full = join(dir, e.name)
75
- if (e.isDirectory()) await walk(full)
76
- else if (e.name.endsWith('.css') && full !== stylesOutFile) cssFiles.push(full)
77
- }
78
- }
79
- await walk(scanDir)
80
- if (cssFiles.length === 0) return false
81
- let css = (await Promise.all(cssFiles.map((f) => readFile(f, 'utf8')))).join('\n')
82
- if (minify) {
83
- const result = await transform(css, { loader: 'css', minify: true })
84
- css = result.code
85
- }
86
- await mkdir(dirname(stylesOutFile), { recursive: true })
87
- await writeFile(stylesOutFile, css)
88
- return true
89
- }
90
-
91
- // ─── CSS collector plugin ─────────────────────────────────────────────────────
92
- //
93
- // Wraps collectCss as an esbuild onEnd plugin. Added to both the routes and
94
- // islands contexts so either rebuild updates the combined stylesheet.
95
-
96
- export function cssCollectorPlugin(dauxDir: string, stylesOutFile: string): Plugin {
97
- return {
98
- name: 'davaux-css-collector',
99
- setup(build) {
100
- build.onEnd(() => void collectCss(dauxDir, stylesOutFile))
101
- },
102
- }
103
- }
104
-
105
- // ─── Island client bundle entry ───────────────────────────────────────────────
106
-
107
- export function generateIslandsEntry(islands: IslandFile[]): string {
108
- return [
109
- `import { hydrate } from 'davaux/client'`,
110
- ...islands.map((isle, i) => `import __island_${i} from ${JSON.stringify(isle.filePath)}`),
111
- '',
112
- 'hydrate({',
113
- ...islands.map(
114
- (isle, i) => ` ${JSON.stringify(isle.id)}: async () => ({ default: __island_${i} }),`,
115
- ),
116
- '})',
117
- ].join('\n')
118
- }