@valancex/cli 0.12.0 → 0.14.0

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 (87) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +69 -11
  3. package/dist/add.d.ts +9 -1
  4. package/dist/add.js +68 -5
  5. package/dist/archive.d.ts +17 -0
  6. package/dist/archive.js +111 -0
  7. package/dist/args.js +2 -2
  8. package/dist/budgets.json +175 -0
  9. package/dist/build.d.ts +11 -0
  10. package/dist/build.js +120 -30
  11. package/dist/check.js +2 -2
  12. package/dist/cli.js +131 -17
  13. package/dist/compile.d.ts +11 -3
  14. package/dist/compile.js +123 -25
  15. package/dist/config.d.ts +13 -0
  16. package/dist/config.js +34 -1
  17. package/dist/contract.d.ts +18 -1
  18. package/dist/contract.js +85 -3
  19. package/dist/dev-desktop.d.ts +8 -0
  20. package/dist/dev-desktop.js +114 -0
  21. package/dist/dev.d.ts +8 -0
  22. package/dist/dev.js +91 -29
  23. package/dist/emit.d.ts +9 -4
  24. package/dist/emit.js +129 -28
  25. package/dist/init.js +14 -4
  26. package/dist/package.d.ts +18 -0
  27. package/dist/package.js +142 -0
  28. package/dist/project.js +1 -1
  29. package/dist/recording-guard.d.ts +5 -0
  30. package/dist/recording-guard.js +28 -0
  31. package/dist/replay.d.ts +15 -0
  32. package/dist/replay.js +59 -0
  33. package/dist/rules.d.ts +23 -0
  34. package/dist/rules.js +123 -0
  35. package/dist/runtime-guard.d.ts +11 -0
  36. package/dist/runtime-guard.js +62 -0
  37. package/dist/security.d.ts +2 -0
  38. package/dist/security.js +8 -1
  39. package/dist/size.d.ts +54 -0
  40. package/dist/size.js +153 -0
  41. package/dist/targets.d.ts +6 -1
  42. package/dist/targets.js +26 -4
  43. package/dist/theme.d.ts +35 -0
  44. package/dist/theme.js +44 -0
  45. package/dist/tree.d.ts +14 -2
  46. package/dist/tree.js +16 -1
  47. package/dist/ui/init.js +4 -4
  48. package/dist/ui/report.js +1 -1
  49. package/dist/ui/run.d.ts +4 -1
  50. package/dist/ui/run.js +18 -3
  51. package/dist/vite.d.ts +3 -2
  52. package/dist/vite.js +3 -3
  53. package/package.json +15 -7
  54. package/schemas/valance.desktop.schema.json +17 -0
  55. package/schemas/valance.schema.json +71 -0
  56. package/templates/desktop/README.md +14 -0
  57. package/templates/desktop/content/404.md +7 -0
  58. package/templates/desktop/content/guide/getting-started.md +15 -0
  59. package/templates/desktop/content/index.md +14 -0
  60. package/templates/desktop/gitignore +7 -0
  61. package/templates/desktop/src/layout.mprx +23 -0
  62. package/templates/desktop/src/main.ts +15 -0
  63. package/templates/desktop/tsconfig.json +18 -0
  64. package/templates/multi/README.md +13 -0
  65. package/templates/multi/content/404.md +7 -0
  66. package/templates/multi/content/guide/getting-started.md +15 -0
  67. package/templates/multi/content/index.md +14 -0
  68. package/templates/multi/src/desktop/layout.mprx +21 -0
  69. package/templates/multi/src/main.ts +23 -0
  70. package/templates/multi/src/web/layout.mprx +27 -0
  71. package/templates/multi/src/web/styles.css +28 -0
  72. package/templates/multi/src/web/theme-toggle.mprx +1 -0
  73. package/templates/multi/src/web/theme-toggle.ts +10 -0
  74. package/templates/web/content/guide/getting-started.md +1 -1
  75. package/templates/web/gitignore +3 -0
  76. package/templates/web/src/layout.mprx +2 -2
  77. package/views/block.mprx +1 -1
  78. package/views/layout.mprx +2 -2
  79. package/views/list-items.mprx +1 -1
  80. package/views-desktop/block.mprx +3 -0
  81. package/views-desktop/blocks.mprx +3 -0
  82. package/views-desktop/inline.mprx +3 -0
  83. package/views-desktop/layout.mprx +20 -0
  84. package/views-desktop/list-block.mprx +3 -0
  85. package/views-desktop/list-items.mprx +3 -0
  86. package/views-desktop/runs.mprx +3 -0
  87. /package/views/{heading.mprx → heading-block.mprx} +0 -0
@@ -0,0 +1,21 @@
1
+ <column>
2
+ <row>
3
+ <link href={home}>{site}</link>
4
+ <button on.click={toggleNavigation()}>{#if navigation}Hide pages{:else}Show pages{/if}</button>
5
+ </row>
6
+ {#if navigation}
7
+ {#each sections as s (s.id)}
8
+ <column>
9
+ {#if s.title != ""}<text>{s.title}</text>{/if}
10
+ <list ordered={false}>
11
+ {#each s.items as n (n.id)}<listitem><link href={n.href}>{n.label}</link></listitem>{/each}
12
+ </list>
13
+ </column>
14
+ {/each}
15
+ {/if}
16
+ <blocks items={blocks} />
17
+ <row>
18
+ {#if prev.href != ""}<link href={prev.href}>{prev.label}</link>{/if}
19
+ {#if next.href != ""}<link href={next.href}>{next.label}</link>{/if}
20
+ </row>
21
+ </column>
@@ -0,0 +1,23 @@
1
+ import { component, defineApp, field } from "@valancex/common";
2
+ import { Schema } from "effect";
3
+ import desktopLayout from "./desktop/layout.mprx";
4
+ import themeToggle from "./web/theme-toggle.js";
5
+ import webLayout from "./web/layout.mprx";
6
+
7
+ // One application, built for each target the project has. What is shared is written once, here: the state (each field is its type and its default, together) and the commands, and the content in
8
+ // content/. What differs is the templates, because each target draws with its own vocabulary: `targets` gives each its layout and its components. Nothing under src/ is part of the application
9
+ // unless it is imported here and listed.
10
+ export default defineApp({
11
+ state: {
12
+ theme: field(Schema.Literal("light", "dark"), "light"), // the web layout's
13
+ navigation: field(Schema.Boolean, true), // the desktop layout's
14
+ },
15
+ commands: (command) => ({
16
+ toggleTheme: command((state) => ({ ...state, theme: state.theme === "light" ? "dark" : "light" })),
17
+ toggleNavigation: command((state) => ({ ...state, navigation: !state.navigation })),
18
+ }),
19
+ targets: {
20
+ web: { layout: component(webLayout), components: [themeToggle] },
21
+ desktop: { layout: component(desktopLayout) },
22
+ },
23
+ });
@@ -0,0 +1,27 @@
1
+ <shell class="layout" theme={theme}>
2
+ <header class="bar">
3
+ <link class="brand" href={home} current="false">{site}</link>
4
+ <theme-toggle theme={theme} on.toggle={toggleTheme()} />
5
+ </header>
6
+ <div class="frame">
7
+ <nav class="sidebar" label="Pages">
8
+ {#each sections as s (s.id)}
9
+ <section>
10
+ {#if s.title != ""}<paragraph class="nav-title">{s.title}</paragraph>{/if}
11
+ <list class="nav-list">
12
+ {#each s.items as n (n.id)}
13
+ <listitem><link class="nav-link" href={n.href} current={n.current}>{n.label}</link></listitem>
14
+ {/each}
15
+ </list>
16
+ </section>
17
+ {/each}
18
+ </nav>
19
+ <main id="content" tabindex="-1">
20
+ <blocks items={blocks} />
21
+ <nav class="pager" label="Previous and next page">
22
+ {#if prev.href != ""}<link class="pager-link" href={prev.href} current="false">{prev.label}</link>{/if}
23
+ {#if next.href != ""}<link class="pager-link" href={next.href} current="false">{next.label}</link>{/if}
24
+ </nav>
25
+ </main>
26
+ </div>
27
+ </shell>
@@ -0,0 +1,28 @@
1
+ :root { --bg: #fff; --fg: #1d2330; --muted: #5c6578; --line: #e3e6ee; --accent: #5b3fd6; --code: #f4f5f9; }
2
+ [data-theme="dark"] { --bg: #12141b; --fg: #e8eaf1; --muted: #9aa3b8; --line: #272b38; --accent: #a78bfa; --code: #1b1e29; }
3
+
4
+ * { box-sizing: border-box; }
5
+ body { margin: 0; font: 16px/1.6 system-ui, sans-serif; background: var(--bg); color: var(--fg); }
6
+ .layout { min-height: 100vh; background: var(--bg); color: var(--fg); }
7
+
8
+ .bar { display: flex; align-items: center; justify-content: space-between; padding: 0.75rem 1.5rem; border-bottom: 1px solid var(--line); }
9
+ .brand { font-weight: 700; color: var(--fg); text-decoration: none; }
10
+ .theme-toggle { font: inherit; padding: 0.25rem 0.75rem; border: 1px solid var(--line); border-radius: 999px; background: transparent; color: var(--fg); cursor: pointer; }
11
+
12
+ .frame { display: grid; grid-template-columns: 14rem 1fr; gap: 2rem; max-width: 60rem; margin: 0 auto; padding: 1.5rem; }
13
+ .sidebar { font-size: 0.95rem; }
14
+ .nav-title { margin: 1rem 0 0.25rem; font-weight: 600; color: var(--muted); text-transform: uppercase; font-size: 0.75rem; letter-spacing: 0.05em; }
15
+ .nav-list { list-style: none; margin: 0; padding: 0; }
16
+ .nav-link { display: block; padding: 0.15rem 0; color: var(--fg); text-decoration: none; }
17
+ .nav-link[aria-current="page"] { color: var(--accent); font-weight: 600; }
18
+
19
+ main { min-width: 0; }
20
+ main h1 { margin-top: 0; }
21
+ a { color: var(--accent); }
22
+ .code { padding: 1rem; overflow-x: auto; background: var(--code); border-radius: 0.5rem; }
23
+ code { font-family: ui-monospace, monospace; font-size: 0.9em; }
24
+ .quote { margin: 1rem 0; padding-left: 1rem; border-left: 3px solid var(--accent); color: var(--muted); }
25
+ .picture { max-width: 100%; }
26
+ .pager { display: flex; justify-content: space-between; margin-top: 3rem; padding-top: 1rem; border-top: 1px solid var(--line); }
27
+
28
+ @media (max-width: 40rem) { .frame { grid-template-columns: 1fr; } }
@@ -0,0 +1 @@
1
+ <button class="theme-toggle" pressed={theme == "dark" ? "true" : "false"} on.click={toggle()}>{theme == "dark" ? "Light" : "Dark"}</button>
@@ -0,0 +1,10 @@
1
+ import { component } from "@valancex/common";
2
+ import { Schema } from "effect";
3
+ import template from "./theme-toggle.mprx";
4
+
5
+ // The interface of `<theme-toggle>`, stated once, where it is defined: what the template reads (`theme`) and what it raises (`toggle`, which carries nothing). Whoever uses it names only that
6
+ // they use it. `.valance/templates.d.ts` gives the template its keys as a type, so a contract that disagrees with the template is an error in the editor.
7
+ export default component(template, {
8
+ props: { theme: Schema.Literal("light", "dark") },
9
+ events: { toggle: Schema.Void },
10
+ });
@@ -21,7 +21,7 @@ Open the address `vlx dev` prints. Edit this file and save: the page reloads wit
21
21
  pnpm build
22
22
  ```
23
23
 
24
- The finished site is in `dist/`. Anything that serves files can host it.
24
+ The finished site is in `dist/web/`. Anything that serves files can host it.
25
25
 
26
26
  ## Where things are
27
27
 
@@ -1,4 +1,7 @@
1
1
  node_modules
2
2
  dist
3
3
  .valance
4
+ # session recordings (vlx dev --record) hold what was typed: never commit them
5
+ .valance/sessions/
6
+ *.session.jsonl
4
7
  .work*
@@ -7,10 +7,10 @@
7
7
  <nav class="sidebar" label="Pages">
8
8
  {#each sections as s (s.id)}
9
9
  <section>
10
- {#if s.title != ""}<para class="nav-title">{s.title}</para>{/if}
10
+ {#if s.title != ""}<paragraph class="nav-title">{s.title}</paragraph>{/if}
11
11
  <list class="nav-list">
12
12
  {#each s.items as n (n.id)}
13
- <item><link class="nav-link" href={n.href} current={n.current}>{n.label}</link></item>
13
+ <listitem><link class="nav-link" href={n.href} current={n.current}>{n.label}</link></listitem>
14
14
  {/each}
15
15
  </list>
16
16
  </section>
package/views/block.mprx CHANGED
@@ -1,3 +1,3 @@
1
1
  <mesh-fragment>
2
- {#if b.kind == "heading"}<heading level={b.level} anchor={b.anchor} spans={b.spans} />{:else if b.kind == "list"}<list-block ordered={b.ordered} items={b.items} />{:else if b.kind == "code"}<pre class="code" tabindex="0"><code>{b.text}</code></pre>{:else if b.kind == "quote"}<quote class="quote"><runs spans={b.spans} /></quote>{:else if b.kind == "image"}<image class="picture" src={b.src} alt={b.alt} loading="lazy" />{:else}<para class="prose"><runs spans={b.spans} /></para>{/if}
2
+ {#if b.kind == "heading"}<heading-block level={b.level} anchor={b.anchor} spans={b.spans} />{:else if b.kind == "list"}<list-block ordered={b.ordered} items={b.items} />{:else if b.kind == "code"}<pre class="code" tabindex="0"><code>{b.text}</code></pre>{:else if b.kind == "quote"}<blockquote class="quote"><runs spans={b.spans} /></blockquote>{:else if b.kind == "image"}<image class="picture" src={b.src} alt={b.alt} loading="lazy" />{:else}<paragraph class="prose"><runs spans={b.spans} /></paragraph>{/if}
3
3
  </mesh-fragment>
package/views/layout.mprx CHANGED
@@ -6,10 +6,10 @@
6
6
  <nav class="sidebar" label="Pages">
7
7
  {#each sections as s (s.id)}
8
8
  <section>
9
- {#if s.title != ""}<para class="nav-title">{s.title}</para>{/if}
9
+ {#if s.title != ""}<paragraph class="nav-title">{s.title}</paragraph>{/if}
10
10
  <list class="nav-list">
11
11
  {#each s.items as n (n.id)}
12
- <item><link class="nav-link" href={n.href} current={n.current}>{n.label}</link></item>
12
+ <listitem><link class="nav-link" href={n.href} current={n.current}>{n.label}</link></listitem>
13
13
  {/each}
14
14
  </list>
15
15
  </section>
@@ -1,3 +1,3 @@
1
1
  <mesh-fragment>
2
- {#each items as i (i.id)}<item><runs spans={i.spans} /></item>{/each}
2
+ {#each items as i (i.id)}<listitem><runs spans={i.spans} /></listitem>{/each}
3
3
  </mesh-fragment>
@@ -0,0 +1,3 @@
1
+ <mesh-fragment>
2
+ {#if b.kind == "heading"}<heading level={b.level}><runs spans={b.spans} /></heading>{:else if b.kind == "list"}<list-block ordered={b.ordered} items={b.items} />{:else if b.kind == "code"}<code>{b.text}</code>{:else if b.kind == "quote"}<blockquote><runs spans={b.spans} /></blockquote>{:else if b.kind == "image"}<image src={b.src} label={b.alt} />{:else}<paragraph><runs spans={b.spans} /></paragraph>{/if}
3
+ </mesh-fragment>
@@ -0,0 +1,3 @@
1
+ <mesh-fragment>
2
+ {#each items as b (b.id)}<block b={b} />{/each}
3
+ </mesh-fragment>
@@ -0,0 +1,3 @@
1
+ <mesh-fragment>
2
+ {#if kind == "strong"}<strong>{text}</strong>{:else if kind == "emphasis"}<emphasis>{text}</emphasis>{:else if kind == "code"}<code>{text}</code>{:else if kind == "link"}<link href={href}>{text}</link>{:else}<mesh-fragment>{text}</mesh-fragment>{/if}
3
+ </mesh-fragment>
@@ -0,0 +1,20 @@
1
+ <column>
2
+ <row>
3
+ <button disabled={!canGoBack} on.click={back()}>Back</button>
4
+ <button disabled={!canGoForward} on.click={forward()}>Forward</button>
5
+ <link href={home}>{site}</link>
6
+ </row>
7
+ {#each sections as s (s.id)}
8
+ <column>
9
+ {#if s.title != ""}<text>{s.title}</text>{/if}
10
+ <list ordered={false}>
11
+ {#each s.items as n (n.id)}<listitem><link href={n.href}>{n.label}</link></listitem>{/each}
12
+ </list>
13
+ </column>
14
+ {/each}
15
+ <blocks items={blocks} />
16
+ <row>
17
+ {#if prev.href != ""}<link href={prev.href}>{prev.label}</link>{/if}
18
+ {#if next.href != ""}<link href={next.href}>{next.label}</link>{/if}
19
+ </row>
20
+ </column>
@@ -0,0 +1,3 @@
1
+ <mesh-fragment>
2
+ <list ordered={ordered}><list-items items={items} /></list>
3
+ </mesh-fragment>
@@ -0,0 +1,3 @@
1
+ <mesh-fragment>
2
+ {#each items as i (i.id)}<listitem><runs spans={i.spans} /></listitem>{/each}
3
+ </mesh-fragment>
@@ -0,0 +1,3 @@
1
+ <mesh-fragment>
2
+ {#each spans as s (s.id)}<inline kind={s.kind} text={s.text} href={s.href} />{/each}
3
+ </mesh-fragment>
File without changes