create-muten 0.0.11 → 0.0.13

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 CHANGED
@@ -1,4 +1,5 @@
1
- # create-muten
1
+ ## ALPHA - STILL ON DEVELOPMENT
2
+ Muten is still under active development. We are currently in the alpha stage and are working on training models with Muten. Please keep in mind that improvements are being made gradually, and version 1.0 has not been released yet.
2
3
 
3
4
  The official scaffolder for **[Muten](https://www.npmjs.com/package/@muten/core)** — an AI-first
4
5
  frontend framework. One command bootstraps a complete, ready-to-run Muten app, so you never copy
@@ -145,16 +146,26 @@ so the whole app is `.muten` from the first line.
145
146
 
146
147
  ## What you can build
147
148
 
148
- A muten app reaches the whole web platform through bounded escapes reach for the **lowest tier that works**:
149
+ **Honest framing first.** muten isn't trying to beat React/Vue/Svelte at being general-purposethey win there.
150
+ muten wins when an **AI builds and maintains the app**: the whole language fits in context, a compiler (`muten
151
+ check`) catches mistakes in milliseconds without a browser, edits stay tiny, and almost no JS ships. Best fit: the
152
+ declarative 80% — CRUD, dashboards, catalogs, content, internal tools. For the rest, you don't fight it — you
153
+ **couple in other tech** through bounded escapes. Reach for the **lowest tier that works**:
149
154
 
150
- - **Pure muten** — CRUD / SaaS / catalog / dashboard / content: pages, routing, `state`/`store`, `query` over
151
- REST, `Form` + validation, `DataTable`, `when`/`each`, SSG + SEO. The declarative 80%, zero extra deps.
155
+ - **Pure muten** — CRUD / SaaS / catalog / dashboard / content: pages, routing, `state`/`store` (with page→store
156
+ action composition), `query` over REST, `Form` (text/number/email/bool/enum + validation), `DataTable`,
157
+ `when`/`each`, SSG + SEO, and the bounded **list toolkit** — inline objects, `patch` in-place edit, `each…where`
158
+ filter, aggregates (`sum`/`count`/`avg`/`min`/`max`), `sort`/`sortDesc`. The declarative 80%, zero extra deps.
152
159
  - **muten + the platform** *(no framework runtime)* — native HTML (`<input type="date">`, `<dialog>`) + `class()`,
153
160
  CSS libs (Tailwind / DaisyUI), **vanilla JS via `Custom`** (charts, maps, date-pickers, rich-text, grids),
154
161
  `use fmt from "./lib.ts"` for any JS logic. Almost every "hard widget" lands here, *without React*.
155
162
  - **Svelte / React island** (`--svelte` / `--react`) — only when the component *is* a framework component
156
163
  (shadcn/ui, a React-only lib). Ships that runtime, lazy + code-split. The narrow last resort.
157
164
 
165
+ **Deploy, honestly:** `npm run dev` runs every tier. For production, pure-muten static content can ship via
166
+ `muten build` (zero-JS HTML); the moment you use `use`/islands/shared cross-page state, deploy with a normal
167
+ `vite build` (it bundles them — the static build doesn't). Most real apps use `vite build`.
168
+
158
169
  Full reference (every primitive, the three tiers, the roadmap): [`@muten/core`](https://www.npmjs.com/package/@muten/core).
159
170
 
160
171
  > **Status: pre-1.0.** The core (language, compiler, CLI, Vite plugin, extension, islands) is solid; the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-muten",
3
- "version": "0.0.11",
3
+ "version": "0.0.13",
4
4
  "description": "Scaffold a new Muten app.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -15,7 +15,7 @@ A page with no reactivity compiles to plain zero-runtime HTML; a reactive one sh
15
15
  - **`src/app.muten` is the entry.** `index.html` loads it; the plugin boots it. **Never create `main.js`** or a `<script>` bootstrap.
16
16
  - Primitives are **PascalCase** (`Stack`, `Text`); keywords/control flow are **lowercase** (`when`, `each`, `state`).
17
17
  - `style(...)` = layout/typography **tokens** (Muten builds STRUCTURE). `class("...")` = **look** (your CSS / Tailwind); toggle reactively with `class(active when isOpen)`. Muten ships no skin.
18
- - `@name` = a state reference. `{expr}` = interpolation inside any string: `Text "Hi, {user.name}"`.
18
+ - `@name` = a state reference. `{expr}` = interpolation inside a Text/label/path string: `Text "Hi, {user.name}"`. (NOT inside `class("…")` — for a dynamic class use `class(name when cond)`.)
19
19
  - Each page has **one root node**. Reactivity is automatic: reading a state in interpolation / `when` / `each` re-renders just that spot.
20
20
 
21
21
  ## 1. What you CAN install / use
@@ -85,10 +85,11 @@ const TAX = 0.21 # compile-time immutable scalar (inlined, never
85
85
 
86
86
  action add mutates users <- item { # mutation; `mutates` lists what it may change (enforced)
87
87
  users.push(item) # ops: push | set | reset | remove
88
+ users.push({ name: item.name, role: "admin" }) # inline object literal — build a record inline
88
89
  if item.vip { rating.set(5) } else { rating.set(1) } # if/else = the only branching in actions
89
90
  }
90
91
 
91
- mock { listUsers: [ { name: "Ana", role: admin } ] } # mock data for a query
92
+ mock { listUsers: [ { name: "Ana", role: "admin" } ] } # mock data (quote text/enum values, like everywhere)
92
93
  sources { listUsers: { url: "https://api…", at: "results" } } # real data source for a query
93
94
  ```
94
95
 
@@ -233,10 +234,17 @@ Responsive: prefix any token with a breakpoint → `md:cols.2`, `lg:cols.4` (`sm
233
234
  - `query` state is async → render with `when @x.loading { … }`, then use `@x.data`.
234
235
  - Mutate **only** through `action`s, and only the state in `mutates` (the linter enforces it):
235
236
  - `list.push(x)` (append; auto-fills uuid fields) · `s.set(v)` · `s.reset()` · `list.remove(x => x.id == id)`
237
+ - **Inline object literal** (build a record without leaving Muten): `posts.push({ title: draft.title, body: draft.body })`, `draft.set({ name: c.name })`. Keys must be real fields of the entity.
238
+ - **Edit / move / toggle an item in place**: `list.patch(x => x.id == c.id, { done: not x.done })` — position-preserving, list ONLY the changed fields. This is the right tool for toggle/update/move (NOT remove+push, which reorders the item to the end).
236
239
  - There is no `toggle`: `flag.set(not flag)`.
237
- - Control flow in the tree: `when <expr> { … }` (mount/unmount), `each <list> as item { … }` (item is a scope var).
240
+ - Control flow in the tree: `when <expr> { … }` (mount/unmount), `each <list> as item { … }` (item is a scope var). Filter a list with `where`: `each posts as p where p.published { … }` renders only matching items.
238
241
  - Expressions: `== != < > <= >=`, `and or not`, `contains` (case-insensitive substring / list membership),
239
242
  `+ - * /`, ternary `c ? a : b`, parentheses, refs (`user.name`, `cart.total`, `$item.x`).
243
+ - **List aggregates** (method + lambda, like `remove`) — for a cart total / KPI count / "N active", NO JS needed:
244
+ - `lines.sum(l => l.price * l.qty)` · `todos.count(t => not t.done)` · `reviews.avg(r => r.score)` · `min/max(x => …)`.
245
+ - `.length` is the count-all; `count(x => cond)` is the filtered count. Works in interpolation, `when`, and store `get`.
246
+ - **Sort a list** (same method+lambda shape; returns a sorted COPY): `each contacts.sort(c => c.name) as c { … }` (ascending) ·
247
+ `each scores.sortDesc(s => s.points) as s { … }` (descending). Use in `each` or a store `get`.
240
248
 
241
249
  ## 9. Stores — app-global state
242
250
  A `.store` file = state shared across pages, **no prop drilling**. The file name is the domain.
@@ -249,6 +257,8 @@ effect { /* runs whenever the store state it reads changes */ }
249
257
  ```
250
258
  Use it from any page/shell by name: `when ui.menuOpen { … }`, `Button "☰" -> ui.toggleMenu`. The Vite
251
259
  plugin auto-detects every `.store` file. `get` = memoized; `effect` = reactive side-effect (Angular-style).
260
+ **A page action can CALL a store action** (composition) — `action add <- d { cart.add(d) draft.reset() }` does
261
+ store work AND local work in one handler (e.g. add to the store, then clear the form). Wire it with `Form submit add`.
252
262
 
253
263
  ## 10. Routing — how it works
254
264
  `src/app.muten` maps URLs to pages. It uses **real paths** (`/about`, History API — client-side nav, no
@@ -8,7 +8,7 @@
8
8
  "lint": "muten lint"
9
9
  },
10
10
  "dependencies": {
11
- "@muten/core": "^0.0.8"
11
+ "@muten/core": "^0.0.10"
12
12
  },
13
13
  "devDependencies": {
14
14
  "vite": "^8.0.16"